bindexplib.cxx

Go to the documentation of this file.
00001 /*
00002 *----------------------------------------------------------------------
00003 * Program:  dumpexts.exe
00004 * Author:   Gordon Chaffee
00005 *
00006 * History:  The real functionality of this file was written by
00007 *           Matt Pietrek in 1993 in his pedump utility.  I've
00008 *           modified it to dump the externals in a bunch of object
00009 *           files to create a .def file.
00010 *
00011 * Notes:    Visual C++ puts an underscore before each exported symbol.
00012 *           This file removes them.  I don't know if this is a problem
00013 *           this other compilers.  If _MSC_VER is defined,
00014 *           the underscore is removed.  If not, it isn't.  To get a
00015 *           full dump of an object file, use the -f option.  This can
00016 *           help determine the something that may be different with a
00017 *           compiler other than Visual C++.
00018 *   ======================================
00019 * Corrections (Axel 2006-04-04):
00020 *   Conversion to C++. Mostly.
00021 *
00022  * Extension (Axel 2006-03-15)
00023  *    As soon as an object file contains an /EXPORT directive (which
00024  *    is generated by the compiler when a symbol is declared as
00025  *    declspec(dllexport)) no to-be-exported symbols are printed,
00026  *    as the linker will see these directives, and if those directives
00027  *    are present we only export selectively (i.e. we trust the
00028  *    programmer).
00029  *
00030  *   ======================================
00031 *   ======================================
00032 * Corrections (Valery Fine 23/02/98):
00033 *
00034 *           The "(vector) deleting destructor" MUST not be exported
00035 *           To recognize it the following test are introduced:
00036 *  "@@UAEPAXI@Z"  scalar deleting dtor
00037 *  "@@QAEPAXI@Z"  vector deleting dtor
00038 *  "AEPAXI@Z"     vector deleting dtor with thunk adjustor
00039 *   ======================================
00040 * Corrections (Valery Fine 12/02/97):
00041 *
00042 *    It created a wrong EXPORTS for the global pointers and constants.
00043 *    The Section Header has been involved to discover the missing information
00044 *    Now the pointers are correctly supplied  supplied with "DATA" descriptor
00045 *        the constants  with no extra descriptor.
00046 *
00047 * Corrections (Valery Fine 16/09/96):
00048 *
00049 *     It didn't work for C++ code with global variables and class definitons
00050 *     The DumpExternalObject function has been introduced to generate .DEF file
00051 *
00052 * Author:   Valery Fine 16/09/96  (E-mail: fine@vxcern.cern.ch)
00053 *----------------------------------------------------------------------
00054 */
00055 
00056 static char sccsid[] = "@(#) winDumpExts.c 1.2 95/10/03 15:27:34";
00057 
00058 #include <windows.h>
00059 #include <stdio.h>
00060 #include <string>
00061 #include <fstream>
00062 
00063 /*
00064 *----------------------------------------------------------------------
00065 * GetArgcArgv --
00066 *
00067 *      Break up a line into argc argv
00068 *----------------------------------------------------------------------
00069 */
00070 int
00071 GetArgcArgv(std::string &s, char **argv)
00072 {
00073    int quote = 0;
00074    int argc = 0;
00075    std::string::iterator bp = s.begin();
00076 
00077    while (1) {
00078       while (isspace(*bp)) {
00079          bp++;
00080       }
00081       if (*bp == '\n' || *bp == '\0') {
00082          *bp = '\0';
00083          return argc;
00084       }
00085       if (*bp == '\"') {
00086          quote = 1;
00087          bp++;
00088       }
00089       argv[argc++] = &(*bp);
00090 
00091       while (*bp != '\0') {
00092          if (quote) {
00093             if (*bp == '\"') {
00094                quote = 0;
00095                *bp = '\0';
00096                bp++;
00097                break;
00098             }
00099             bp++;
00100             continue;
00101          }
00102          if (isspace(*bp)) {
00103             *bp = '\0';
00104             bp++;
00105             break;
00106          }
00107          bp++;
00108       }
00109    }
00110 }
00111 
00112 /*
00113 *  The names of the first group of possible symbol table storage classes
00114 */
00115 char * SzStorageClass1[] = {
00116    "NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
00117    "UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
00118    "MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
00119    "ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
00120 };
00121 
00122 /*
00123 * The names of the second group of possible symbol table storage classes
00124 */
00125 char * SzStorageClass2[] = {
00126    "BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
00127 };
00128 
00129 /*
00130 *----------------------------------------------------------------------
00131 * GetSZStorageClass --
00132 *
00133 *      Given a symbol storage class value, return a descriptive
00134 *      ASCII string
00135 *----------------------------------------------------------------------
00136 */
00137 PSTR
00138 GetSZStorageClass(BYTE storageClass)
00139 {
00140    if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
00141       return SzStorageClass1[storageClass];
00142    else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
00143       && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
00144       return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
00145    else
00146       return "???";
00147 }
00148 
00149 void AddHex(std::string& buf, long val, bool caps=false)
00150 {
00151    buf += "0x";
00152    int len=buf.length();
00153    while (val) {
00154       char hex = (char)(val & 16);
00155       val = val >> 4;
00156       if (hex<10) hex+='0';
00157       else if (caps) hex+='A'-10;
00158       else hex+='a'-10;
00159       buf.insert(len, hex, 1);
00160    }
00161 }
00162 
00163 /*
00164 *----------------------------------------------------------------------
00165 * GetSectionName --
00166 *
00167 *      Used by DumpSymbolTable, it gives meaningful names to
00168 *      the non-normal section number.
00169 *
00170 * Results:
00171 *      A name is returned in buffer
00172 *----------------------------------------------------------------------
00173 */
00174 void
00175 GetSectionName(PIMAGE_SYMBOL pSymbolTable, std::string& buffer)
00176 {
00177    DWORD section;
00178 
00179    section = pSymbolTable->SectionNumber;
00180 
00181    switch ( (SHORT)section )
00182    {
00183    case IMAGE_SYM_UNDEFINED: if (pSymbolTable->Value) buffer += "COMM"; else buffer += "UNDEF"; break;
00184    case IMAGE_SYM_ABSOLUTE:  buffer += "ABS  "; break;
00185    case IMAGE_SYM_DEBUG:     buffer += "DEBUG"; break;
00186    default: AddHex(buffer, section, true);
00187    }
00188 }
00189 
00190 /*
00191 *----------------------------------------------------------------------
00192 * GetSectionCharacteristics --
00193 *
00194 *      Converts the Characteristics field of IMAGE_SECTION_HEADER
00195 *      to print.
00196 *
00197 *  Results:
00198 *       A definiton of the section symbol type
00199 *----------------------------------------------------------------------
00200 */
00201 void
00202 GetSectionCharacteristics(PIMAGE_SECTION_HEADER pSectionHeaders, int nSectNum, std::string &buffer)
00203 {
00204    DWORD SectChar;
00205    std::string TempBuf;
00206    buffer.clear();
00207    if (nSectNum > 0) {
00208       SectChar = pSectionHeaders[nSectNum-1].Characteristics;
00209 
00210       buffer = " ";
00211       AddHex(buffer, SectChar);
00212       if       (SectChar & IMAGE_SCN_CNT_CODE)                buffer += " Code";
00213       else if  (SectChar & IMAGE_SCN_CNT_INITIALIZED_DATA)    buffer += " Init. data";
00214       else if  (SectChar & IMAGE_SCN_CNT_UNINITIALIZED_DATA ) buffer += " UnInit data";
00215       else                                                    buffer += " Unknow type";
00216 
00217       if   (SectChar & IMAGE_SCN_MEM_READ)  {
00218          buffer += " Read";
00219          if (SectChar & IMAGE_SCN_MEM_WRITE)
00220             buffer += " and Write";
00221          else buffer += " only";
00222       }
00223       else if (SectChar & IMAGE_SCN_MEM_WRITE)
00224          buffer +=" Write only";
00225 
00226    }
00227 }
00228 
00229 /*
00230 *----------------------------------------------------------------------
00231 * DumpSymbolTable --
00232 *
00233 *      Dumps a COFF symbol table from an EXE or OBJ.  We only use
00234 *      it to dump tables from OBJs.
00235 *----------------------------------------------------------------------
00236 */
00237 void
00238 DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout, unsigned cSymbols)
00239 {
00240    unsigned i;
00241    PSTR stringTable;
00242    std::string sectionName;
00243    std::string sectionCharacter;
00244    int iSectNum;
00245 
00246    fprintf(fout, "Symbol Table - %X entries  (* = auxillary symbol)\n",
00247       cSymbols);
00248 
00249    fprintf(fout,
00250       "Indx Name                 Value    Section    cAux  Type    Storage  Character\n"
00251       "---- -------------------- -------- ---------- ----- ------- -------- ---------\n");
00252 
00253    /*
00254    * The string table apparently starts right after the symbol table
00255    */
00256    stringTable = (PSTR)&pSymbolTable[cSymbols];
00257 
00258    for ( i=0; i < cSymbols; i++ ) {
00259       fprintf(fout, "%04X ", i);
00260       if ( pSymbolTable->N.Name.Short != 0 )
00261          fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
00262       else
00263          fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
00264 
00265       fprintf(fout, " %08X", pSymbolTable->Value);
00266 
00267       iSectNum = pSymbolTable->SectionNumber;
00268       GetSectionName(pSymbolTable, sectionName);
00269       fprintf(fout, " sect:%s aux:%X type:%02X st:%s",
00270          sectionName.c_str(),
00271          pSymbolTable->NumberOfAuxSymbols,
00272          pSymbolTable->Type,
00273          GetSZStorageClass(pSymbolTable->StorageClass) );
00274 
00275       GetSectionCharacteristics(pSectionHeaders,iSectNum,sectionCharacter);
00276       fprintf(fout," hc: %s \n",sectionCharacter.c_str());
00277 #if 0
00278       if ( pSymbolTable->NumberOfAuxSymbols )
00279          DumpAuxSymbols(pSymbolTable);
00280 #endif
00281 
00282       /*
00283       * Take into account any aux symbols
00284       */
00285       i += pSymbolTable->NumberOfAuxSymbols;
00286       pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
00287       pSymbolTable++;
00288    }
00289 }
00290 
00291 /*
00292 *----------------------------------------------------------------------
00293 * DumpExternals --
00294 *
00295 *      Dumps a COFF symbol table from an EXE or OBJ.  We only use
00296 *      it to dump tables from OBJs.
00297 *----------------------------------------------------------------------
00298 */
00299 void
00300 DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
00301 {
00302    unsigned i;
00303    PSTR stringTable;
00304    std::string symbol;
00305 
00306    /*
00307    * The string table apparently starts right after the symbol table
00308    */
00309    stringTable = (PSTR)&pSymbolTable[cSymbols];
00310 
00311    for ( i=0; i < cSymbols; i++ ) {
00312       if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
00313          if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
00314             if (pSymbolTable->N.Name.Short != 0) {
00315                symbol = "";
00316                symbol.insert(0, (const char *)(pSymbolTable->N.ShortName), 8);
00317             } else {
00318                symbol = stringTable + pSymbolTable->N.Name.Long;
00319             }
00320             std::string::size_type posAt = symbol.find('@');
00321             if (posAt != std::string::npos) symbol.erase(posAt);
00322 #ifndef _MSC_VER
00323             fprintf(fout, "\t%s\n", symbol.c_str());
00324 #else
00325             fprintf(fout, "\t%s\n", symbol.c_str()+1);
00326 #endif
00327          }
00328       }
00329 
00330       /*
00331       * Take into account any aux symbols
00332       */
00333       i += pSymbolTable->NumberOfAuxSymbols;
00334       pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
00335       pSymbolTable++;
00336    }
00337 }
00338 
00339 /*
00340 + * Utility func, strstr with size
00341 + */
00342 const char* StrNStr(const char* start, const char* find, size_t &size) {
00343    int len;
00344    const char* hint;
00345 
00346    if (!start || !find || !size) {
00347       size = 0;
00348       return 0;
00349    }
00350    len = strlen(find);
00351 
00352    while (hint = (const char*) memchr(start, find[0], size-len+1)) {
00353       size -= (hint - start);
00354       if (!strncmp(hint, find, len))
00355          return hint;
00356       start = hint + 1;
00357    }
00358 
00359    size = 0;
00360    return 0;
00361 }
00362 
00363 /*
00364  *----------------------------------------------------------------------
00365  * HaveExportedObjects --
00366  *
00367  *      Returns >0 if export directives (declspec(dllexport)) exist.
00368  *
00369  *----------------------------------------------------------------------
00370  */
00371 int
00372 HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout)
00373 {
00374     static int fImportFlag = 0;  /*  The status is nor defined yet */
00375     WORD i;
00376     size_t size;
00377     char foundExports;
00378     const char * rawdata;
00379 
00380     PIMAGE_SECTION_HEADER pDirectivesSectionHeader;
00381 
00382     if (fImportFlag) return 1;
00383 
00384     i = 0;
00385     foundExports = 0;
00386     pDirectivesSectionHeader = 0;
00387     for(i = 0; i < pImageFileHeader->NumberOfSections && !pDirectivesSectionHeader; i++)
00388        if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8))
00389           pDirectivesSectionHeader = &pSectionHeaders[i];
00390    if (!pDirectivesSectionHeader) return 0;
00391 
00392     rawdata=(const char*)pImageFileHeader+pDirectivesSectionHeader->PointerToRawData;
00393     if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
00394 
00395     size = pDirectivesSectionHeader->SizeOfRawData;
00396     const char* posImportFlag = rawdata;
00397     while ((posImportFlag = StrNStr(posImportFlag, " /EXPORT:", size))) {
00398        const char* lookingForDict = posImportFlag + 9;
00399        if (!strncmp(lookingForDict, "_G__cpp_",8) ||
00400            !strncmp(lookingForDict, "_G__set_cpp_",12)) {
00401           posImportFlag = lookingForDict;
00402           continue;
00403        }
00404 
00405        const char* lookingForDATA = posImportFlag + 9;
00406        while (*(++lookingForDATA) && *lookingForDATA != ' ');
00407        lookingForDATA -= 5;
00408        // ignore DATA exports
00409        if (strncmp(lookingForDATA, ",DATA", 5)) break;
00410        posImportFlag = lookingForDATA + 5;
00411     }
00412     fImportFlag = (int)posImportFlag;
00413     return fImportFlag;
00414 }
00415 
00416 
00417 
00418 /*
00419  *----------------------------------------------------------------------
00420 * DumpExternalsObjects --
00421 *
00422 *      Dumps a COFF symbol table from an EXE or OBJ.  We only use
00423 *      it to dump tables from OBJs.
00424 *----------------------------------------------------------------------
00425 */
00426 void
00427 DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders,
00428                      FILE *fout, unsigned cSymbols, int fort)
00429 {
00430    unsigned i;
00431    PSTR stringTable;
00432    std::string symbol;
00433    DWORD SectChar;
00434    static int fImportFlag = -1;  /*  The status is nor defined yet */
00435 
00436    /*
00437    * The string table apparently starts right after the symbol table
00438    */
00439    stringTable = (PSTR)&pSymbolTable[cSymbols];
00440 
00441    for ( i=0; i < cSymbols; i++ ) {
00442       if (pSymbolTable->SectionNumber > 0 && ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
00443          if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
00444             /*
00445             *    The name of the Function entry points
00446             */
00447             if (pSymbolTable->N.Name.Short != 0) {
00448                symbol = "";
00449                symbol.insert(0, (const char *)pSymbolTable->N.ShortName, 8);
00450             } else {
00451                symbol = stringTable + pSymbolTable->N.Name.Long;
00452             }
00453 
00454             while (isspace(symbol[0])) symbol.erase(0,1);
00455 #ifdef _MSC_VER
00456             if (symbol[0] == '_') symbol.erase(0,1);
00457             if (fort) {
00458                std::string::size_type posAt = symbol.find('@');
00459                if (posAt != std::string::npos) symbol.erase(posAt);
00460             }
00461 #endif
00462             if (fImportFlag) {
00463                fImportFlag = 0;
00464                fprintf(fout,"EXPORTS \n");
00465             }
00466             /*
00467             Check whether it is "Scalar deleting destructor" and
00468             "Vector deleting destructor"
00469             */
00470             /*
00471             if (!strstr(s,"@@UAEPAXI@Z") && !strstr(s,"@@QAEPAXI@Z") &&
00472             !strstr(s,"@AEPAXI@Z")   && !strstr(s,"AEPAXI@Z")    &&
00473             !strstr(s,"real@"))
00474             */
00475             const char *scalarPrefix = "??_G";
00476             const char *vectorPrefix = "??_E";
00477             if (symbol.compare(0, 4, scalarPrefix) &&
00478                symbol.compare(0, 4, vectorPrefix) &&
00479                symbol.find("real@") == std::string::npos)
00480             {
00481                SectChar = pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
00482                if (!pSymbolTable->Type  && (SectChar & IMAGE_SCN_MEM_WRITE)) {
00483                   // Read only (i.e. constants) must be excluded
00484                   fprintf(fout, "\t%s \t DATA\n", symbol.c_str());
00485                } else {
00486                   if ( pSymbolTable->Type  || !(SectChar & IMAGE_SCN_MEM_READ)) {
00487                      fprintf(fout, "\t%s\n", symbol.c_str());
00488                   } else {
00489                      //                    printf(" strange symbol: %s \n",s);
00490                   }
00491                }
00492             }
00493          }
00494       }
00495       else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED && !pSymbolTable->Type && 0){
00496          /*
00497          *    The IMPORT global variable entry points
00498          */
00499          if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
00500             symbol = stringTable + pSymbolTable->N.Name.Long;
00501             while (isspace(symbol[0]))  symbol.erase(0,1);
00502             if (symbol[0] == '_') symbol.erase(0,1);
00503             if (!fImportFlag) {
00504                fImportFlag = 1;
00505                fprintf(fout,"IMPORTS \n");
00506             }
00507             fprintf(fout, "\t%s DATA \n", symbol.c_str()+1);
00508          }
00509       }
00510 
00511       /*
00512       * Take into account any aux symbols
00513       */
00514       i += pSymbolTable->NumberOfAuxSymbols;
00515       pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
00516       pSymbolTable++;
00517    }
00518 }
00519 
00520 /*
00521 *----------------------------------------------------------------------
00522 * DumpObjFile --
00523 *
00524 *      Dump an object file--either a full listing or just the exported
00525 *      symbols.
00526 *----------------------------------------------------------------------
00527 */
00528 void
00529 DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full, int fort)
00530 {
00531    PIMAGE_SYMBOL PCOFFSymbolTable;
00532    PIMAGE_SECTION_HEADER PCOFFSectionHeaders;
00533    DWORD COFFSymbolCount;
00534 
00535    PCOFFSymbolTable = (PIMAGE_SYMBOL)
00536       ((DWORD)pImageFileHeader + pImageFileHeader->PointerToSymbolTable);
00537    COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
00538 
00539    PCOFFSectionHeaders = (PIMAGE_SECTION_HEADER)
00540       ((DWORD)pImageFileHeader          +
00541       IMAGE_SIZEOF_FILE_HEADER +
00542       pImageFileHeader->SizeOfOptionalHeader);
00543 
00544 
00545    if (full) {
00546       DumpSymbolTable(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount);
00547    } else {
00548         int haveExports = HaveExportedObjects(pImageFileHeader, PCOFFSectionHeaders, fout);
00549         if (!haveExports)
00550             DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount, fort);   
00551    }
00552 }
00553 
00554 /*
00555 *----------------------------------------------------------------------
00556 * DumpFile --
00557 *
00558 *      Open up a file, memory map it, and call the appropriate
00559 *      dumping routine
00560 *----------------------------------------------------------------------
00561 */
00562 void
00563 DumpFile(LPSTR filename, FILE *fout, int full, int fort)
00564 {
00565    HANDLE hFile;
00566    HANDLE hFileMapping;
00567    LPVOID lpFileBase;
00568    PIMAGE_DOS_HEADER dosHeader;
00569 
00570    hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
00571       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
00572 
00573    if (hFile == INVALID_HANDLE_VALUE) {
00574       fprintf(stderr, "Couldn't open file with CreateFile()\n");
00575       return;
00576    }
00577 
00578    hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
00579    if (hFileMapping == 0) {
00580       CloseHandle(hFile);
00581       fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
00582       return;
00583    }
00584 
00585    lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
00586    if (lpFileBase == 0) {
00587       CloseHandle(hFileMapping);
00588       CloseHandle(hFile);
00589       fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
00590       return;
00591    }
00592 
00593    dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
00594    if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
00595 #if 0
00596       DumpExeFile( dosHeader );
00597 #else
00598       fprintf(stderr, "File is an executable.  I don't dump those.\n");
00599       return;
00600 #endif
00601    }
00602    /* Does it look like a i386 COFF OBJ file??? */
00603    else if ((dosHeader->e_magic == 0x014C) && (dosHeader->e_sp == 0)) {
00604       /*
00605       * The two tests above aren't what they look like.  They're
00606       * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
00607       * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
00608       */
00609       DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full, fort);
00610    } else {
00611       printf("unrecognized file format\n");
00612    }
00613    UnmapViewOfFile(lpFileBase);
00614    CloseHandle(hFileMapping);
00615    CloseHandle(hFile);
00616 }
00617 
00618 void
00619 main(int argc, char **argv)
00620 {
00621    std::string cmdline;
00622    int i, arg;
00623    FILE *fout;
00624    int full = 0;
00625    int fort = 0;
00626    char *dllname = "";
00627    char *outfile = NULL;
00628 
00629    if (argc < 3) {
00630 Usage:
00631       fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
00632       exit(1);
00633    }
00634 
00635    arg = 1;
00636    while (argv[arg][0] == '-') {
00637       if (strcmp(argv[arg], "--") == 0) {
00638          arg++;
00639          break;
00640       } else if (strcmp(argv[arg], "-f") == 0) {
00641          full = 1;
00642       } else if (strcmp(argv[arg], "-x") == 0) {
00643          fort = 1;
00644       } else if (strcmp(argv[arg], "-o") == 0) {
00645          arg++;
00646          if (arg == argc) {
00647             goto Usage;
00648          }
00649          outfile = argv[arg];
00650       }
00651       arg++;
00652    }
00653    if (arg == argc) {
00654       goto Usage;
00655    }
00656 
00657    if (outfile) {
00658       fout = fopen(outfile, "w+");
00659       if (fout == NULL) {
00660          fprintf(stderr, "Unable to open \'%s\' for writing:\n",
00661             argv[arg]);
00662          perror("");
00663          exit(1);
00664       }
00665    } else {
00666       fout = stdout;
00667    }
00668 
00669    if (! full) {
00670       dllname = argv[arg];
00671       arg++;
00672       if (arg == argc) {
00673          goto Usage;
00674       }
00675       fprintf(fout, "LIBRARY    %s\n", dllname);
00676 #ifndef _X86_
00677       fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
00678       fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
00679 #endif
00680    }
00681 
00682    for (; arg < argc; arg++) {
00683       WIN32_FIND_DATA FindFileData;
00684       HANDLE SearchFile;
00685       if (argv[arg][0] == '@') {
00686          std::ifstream fargs(&argv[arg][1]);
00687          if (!fargs) {
00688             fprintf(stderr, "Unable to open \'%s\' for reading:\n",
00689                argv[arg]);
00690             perror("");
00691             exit(1);
00692          }
00693          char *fargv[1000];
00694          for (i = 0; i < arg; i++) {
00695             cmdline += argv[i];
00696             fargv[i] = argv[i];
00697          }
00698          std::string line;
00699          std::getline(fargs, line);
00700          cmdline += line;
00701          fprintf(stderr, "%s\n", line.c_str());
00702          i += GetArgcArgv(line, &fargv[i]);
00703          argc = i;
00704          argv = fargv;
00705       }
00706       /*
00707       *  Argument can contain the wildcard names
00708       */
00709       SearchFile = FindFirstFile(argv[arg],&FindFileData);
00710       if (SearchFile == INVALID_HANDLE_VALUE){
00711          fprintf(stderr, "Unable to find \'%s\' for reading:\n",
00712             argv[arg]);
00713          exit(1);
00714       }
00715       else  {
00716          /*
00717          *  Since WIN32_FIND_DATA has no path information one has to extract it himself.
00718          */
00719          TCHAR *filename = argv[arg];
00720          TCHAR path[2048];
00721          int i = strlen(filename);
00722          i--;
00723          while( filename[i] != '\\' && filename[i] != '/'  && i >=0) i--;
00724          do
00725          {
00726             if (i >= 0) strncpy( path, filename, i+1); /* Generate the 'path' info */
00727             path[i+1] = '\0';
00728             DumpFile(strcat(path, FindFileData.cFileName), fout, full, fort);
00729          } while (FindNextFile(SearchFile,&FindFileData));
00730 
00731 
00732          FindClose(SearchFile);
00733       }
00734    }
00735    exit(0);
00736 }

Generated on Tue Jul 5 14:10:18 2011 for ROOT_528-00b_version by  doxygen 1.5.1