summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2015-06-19 20:12:43 (GMT)
committerBrad King <brad.king@kitware.com>2015-07-06 15:10:58 (GMT)
commit65086ad778b5d8312e4168fc5ed670e545be7d4b (patch)
treea3082dc3563b2af8e5ed6234a8d8d04bfdc23e81 /Source
parent2fd05f411b758e4060b537a6c9461634ad1362b2 (diff)
downloadCMake-65086ad778b5d8312e4168fc5ed670e545be7d4b.zip
CMake-65086ad778b5d8312e4168fc5ed670e545be7d4b.tar.gz
CMake-65086ad778b5d8312e4168fc5ed670e545be7d4b.tar.bz2
bindexplib: Import original implementation from CERN
Download the original implementation provided by root.cern.ch with the following session: $ wget https://raw.githubusercontent.com/gordonwatts/root-vc-port/f0ee59af/build/win/bindexplib/bindexplib.cxx $ sha1sum bindexplib.cxx fa6efafb2c58a0644bd0f6a56fe02ee0d55c7fcd bindexplib.cxx $ sed -i 's/ *$//;s/'$'\t''/ /' bindexplib.cxx
Diffstat (limited to 'Source')
-rw-r--r--Source/bindexplib.cxx739
1 files changed, 739 insertions, 0 deletions
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
new file mode 100644
index 0000000..6f9605c
--- /dev/null
+++ b/Source/bindexplib.cxx
@@ -0,0 +1,739 @@
+/*
+*----------------------------------------------------------------------
+* Program: dumpexts.exe
+* Author: Gordon Chaffee
+*
+* History: The real functionality of this file was written by
+* Matt Pietrek in 1993 in his pedump utility. I've
+* modified it to dump the externals in a bunch of object
+* files to create a .def file.
+*
+* Notes: Visual C++ puts an underscore before each exported symbol.
+* This file removes them. I don't know if this is a problem
+* this other compilers. If _MSC_VER is defined,
+* the underscore is removed. If not, it isn't. To get a
+* full dump of an object file, use the -f option. This can
+* help determine the something that may be different with a
+* compiler other than Visual C++.
+* ======================================
+* Corrections (Axel 2006-04-04):
+* Conversion to C++. Mostly.
+*
+ * Extension (Axel 2006-03-15)
+ * As soon as an object file contains an /EXPORT directive (which
+ * is generated by the compiler when a symbol is declared as
+ * declspec(dllexport)) no to-be-exported symbols are printed,
+ * as the linker will see these directives, and if those directives
+ * are present we only export selectively (i.e. we trust the
+ * programmer).
+ *
+ * ======================================
+* ======================================
+* Corrections (Valery Fine 23/02/98):
+*
+* The "(vector) deleting destructor" MUST not be exported
+* To recognize it the following test are introduced:
+* "@@UAEPAXI@Z" scalar deleting dtor
+* "@@QAEPAXI@Z" vector deleting dtor
+* "AEPAXI@Z" vector deleting dtor with thunk adjustor
+* ======================================
+* Corrections (Valery Fine 12/02/97):
+*
+* It created a wrong EXPORTS for the global pointers and constants.
+* The Section Header has been involved to discover the missing information
+* Now the pointers are correctly supplied supplied with "DATA" descriptor
+* the constants with no extra descriptor.
+*
+* Corrections (Valery Fine 16/09/96):
+*
+* It didn't work for C++ code with global variables and class definitons
+* The DumpExternalObject function has been introduced to generate .DEF file
+*
+* Author: Valery Fine 16/09/96 (E-mail: fine@vxcern.cern.ch)
+*----------------------------------------------------------------------
+*/
+
+static char sccsid[] = "@(#) winDumpExts.c 1.2 95/10/03 15:27:34";
+
+#include <windows.h>
+#include <stdio.h>
+#include <string>
+#include <fstream>
+
+/*
+*----------------------------------------------------------------------
+* GetArgcArgv --
+*
+* Break up a line into argc argv
+*----------------------------------------------------------------------
+*/
+int
+GetArgcArgv(std::string &s, char **argv)
+{
+ int quote = 0;
+ int argc = 0;
+ std::string::iterator bp = s.begin();
+
+ while (1) {
+ while (isspace(*bp)) {
+ bp++;
+ }
+ if (*bp == '\n' || *bp == '\0') {
+ *bp = '\0';
+ return argc;
+ }
+ if (*bp == '\"') {
+ quote = 1;
+ bp++;
+ }
+ argv[argc++] = &(*bp);
+
+ while (*bp != '\0') {
+ if (quote) {
+ if (*bp == '\"') {
+ quote = 0;
+ *bp = '\0';
+ bp++;
+ break;
+ }
+ bp++;
+ continue;
+ }
+ if (isspace(*bp)) {
+ *bp = '\0';
+ bp++;
+ break;
+ }
+ bp++;
+ }
+ }
+}
+
+/*
+* The names of the first group of possible symbol table storage classes
+*/
+char * SzStorageClass1[] = {
+ "NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
+ "UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
+ "MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
+ "ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
+};
+
+/*
+* The names of the second group of possible symbol table storage classes
+*/
+char * SzStorageClass2[] = {
+ "BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
+};
+
+/*
+*----------------------------------------------------------------------
+* GetSZStorageClass --
+*
+* Given a symbol storage class value, return a descriptive
+* ASCII string
+*----------------------------------------------------------------------
+*/
+PSTR
+GetSZStorageClass(BYTE storageClass)
+{
+ if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
+ return SzStorageClass1[storageClass];
+ else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
+ && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
+ return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
+ else
+ return "???";
+}
+
+void AddHex(std::string& buf, long val, bool caps=false)
+{
+ buf += "0x";
+ size_t len=buf.length();
+ while (val) {
+ char hex = (char)(val & 16);
+ val = val >> 4;
+ if (hex<10) hex+='0';
+ else if (caps) hex+='A'-10;
+ else hex+='a'-10;
+ buf.insert(len, hex, 1);
+ }
+}
+
+/*
+*----------------------------------------------------------------------
+* GetSectionName --
+*
+* Used by DumpSymbolTable, it gives meaningful names to
+* the non-normal section number.
+*
+* Results:
+* A name is returned in buffer
+*----------------------------------------------------------------------
+*/
+void
+GetSectionName(PIMAGE_SYMBOL pSymbolTable, std::string& buffer)
+{
+ DWORD section;
+
+ section = pSymbolTable->SectionNumber;
+
+ switch ( (SHORT)section )
+ {
+ case IMAGE_SYM_UNDEFINED: if (pSymbolTable->Value) buffer += "COMM"; else buffer += "UNDEF"; break;
+ case IMAGE_SYM_ABSOLUTE: buffer += "ABS "; break;
+ case IMAGE_SYM_DEBUG: buffer += "DEBUG"; break;
+ default: AddHex(buffer, section, true);
+ }
+}
+
+/*
+*----------------------------------------------------------------------
+* GetSectionCharacteristics --
+*
+* Converts the Characteristics field of IMAGE_SECTION_HEADER
+* to print.
+*
+* Results:
+* A definiton of the section symbol type
+*----------------------------------------------------------------------
+*/
+void
+GetSectionCharacteristics(PIMAGE_SECTION_HEADER pSectionHeaders, int nSectNum, std::string &buffer)
+{
+ DWORD SectChar;
+ std::string TempBuf;
+ buffer.clear();
+ if (nSectNum > 0) {
+ SectChar = pSectionHeaders[nSectNum-1].Characteristics;
+
+ buffer = " ";
+ AddHex(buffer, SectChar);
+ if (SectChar & IMAGE_SCN_CNT_CODE) buffer += " Code";
+ else if (SectChar & IMAGE_SCN_CNT_INITIALIZED_DATA) buffer += " Init. data";
+ else if (SectChar & IMAGE_SCN_CNT_UNINITIALIZED_DATA ) buffer += " UnInit data";
+ else buffer += " Unknow type";
+
+ if (SectChar & IMAGE_SCN_MEM_READ) {
+ buffer += " Read";
+ if (SectChar & IMAGE_SCN_MEM_WRITE)
+ buffer += " and Write";
+ else buffer += " only";
+ }
+ else if (SectChar & IMAGE_SCN_MEM_WRITE)
+ buffer +=" Write only";
+
+ }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpSymbolTable --
+*
+* Dumps a COFF symbol table from an EXE or OBJ. We only use
+* it to dump tables from OBJs.
+*----------------------------------------------------------------------
+*/
+void
+DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout, unsigned cSymbols)
+{
+ unsigned i;
+ PSTR stringTable;
+ std::string sectionName;
+ std::string sectionCharacter;
+ int iSectNum;
+
+ fprintf(fout, "Symbol Table - %X entries (* = auxillary symbol)\n",
+ cSymbols);
+
+ fprintf(fout,
+ "Indx Name Value Section cAux Type Storage Character\n"
+ "---- -------------------- -------- ---------- ----- ------- -------- ---------\n");
+
+ /*
+ * The string table apparently starts right after the symbol table
+ */
+ stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+ for ( i=0; i < cSymbols; i++ ) {
+ fprintf(fout, "%04X ", i);
+ if ( pSymbolTable->N.Name.Short != 0 )
+ fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
+ else
+ fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
+
+ fprintf(fout, " %08X", pSymbolTable->Value);
+
+ iSectNum = pSymbolTable->SectionNumber;
+ GetSectionName(pSymbolTable, sectionName);
+ fprintf(fout, " sect:%s aux:%X type:%02X st:%s",
+ sectionName.c_str(),
+ pSymbolTable->NumberOfAuxSymbols,
+ pSymbolTable->Type,
+ GetSZStorageClass(pSymbolTable->StorageClass) );
+
+ GetSectionCharacteristics(pSectionHeaders,iSectNum,sectionCharacter);
+ fprintf(fout," hc: %s \n",sectionCharacter.c_str());
+#if 0
+ if ( pSymbolTable->NumberOfAuxSymbols )
+ DumpAuxSymbols(pSymbolTable);
+#endif
+
+ /*
+ * Take into account any aux symbols
+ */
+ i += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable++;
+ }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpExternals --
+*
+* Dumps a COFF symbol table from an EXE or OBJ. We only use
+* it to dump tables from OBJs.
+*----------------------------------------------------------------------
+*/
+void
+DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
+{
+ unsigned i;
+ PSTR stringTable;
+ std::string symbol;
+
+ /*
+ * The string table apparently starts right after the symbol table
+ */
+ stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+ for ( i=0; i < cSymbols; i++ ) {
+ if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
+ if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+ if (pSymbolTable->N.Name.Short != 0) {
+ symbol = "";
+ symbol.insert(0, (const char *)(pSymbolTable->N.ShortName), 8);
+ } else {
+ symbol = stringTable + pSymbolTable->N.Name.Long;
+ }
+ std::string::size_type posAt = symbol.find('@');
+ if (posAt != std::string::npos) symbol.erase(posAt);
+#ifndef _MSC_VER
+ fprintf(fout, "\t%s\n", symbol.c_str());
+#else
+ fprintf(fout, "\t%s\n", symbol.c_str()+1);
+#endif
+ }
+ }
+
+ /*
+ * Take into account any aux symbols
+ */
+ i += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable++;
+ }
+}
+
+/*
++ * Utility func, strstr with size
++ */
+const char* StrNStr(const char* start, const char* find, size_t &size) {
+ size_t len;
+ const char* hint;
+
+ if (!start || !find || !size) {
+ size = 0;
+ return 0;
+ }
+ len = strlen(find);
+
+ while (hint = (const char*) memchr(start, find[0], size-len+1)) {
+ size -= (hint - start);
+ if (!strncmp(hint, find, len))
+ return hint;
+ start = hint + 1;
+ }
+
+ size = 0;
+ return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ * HaveExportedObjects --
+ *
+ * Returns >0 if export directives (declspec(dllexport)) exist.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout)
+{
+ static int fImportFlag = 0; /* The status is nor defined yet */
+ WORD i;
+ size_t size;
+ char foundExports;
+ const char * rawdata;
+
+ PIMAGE_SECTION_HEADER pDirectivesSectionHeader;
+
+ if (fImportFlag) return 1;
+
+ i = 0;
+ foundExports = 0;
+ pDirectivesSectionHeader = 0;
+ for(i = 0; i < pImageFileHeader->NumberOfSections && !pDirectivesSectionHeader; i++)
+ if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8))
+ pDirectivesSectionHeader = &pSectionHeaders[i];
+ if (!pDirectivesSectionHeader) return 0;
+
+ rawdata=(const char*)pImageFileHeader+pDirectivesSectionHeader->PointerToRawData;
+ if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
+
+ size = pDirectivesSectionHeader->SizeOfRawData;
+ const char* posImportFlag = rawdata;
+ while ((posImportFlag = StrNStr(posImportFlag, " /EXPORT:", size))) {
+ const char* lookingForDict = posImportFlag + 9;
+ if (!strncmp(lookingForDict, "_G__cpp_",8) ||
+ !strncmp(lookingForDict, "_G__set_cpp_",12)) {
+ posImportFlag = lookingForDict;
+ continue;
+ }
+
+ const char* lookingForDATA = posImportFlag + 9;
+ while (*(++lookingForDATA) && *lookingForDATA != ' ');
+ lookingForDATA -= 5;
+ // ignore DATA exports
+ if (strncmp(lookingForDATA, ",DATA", 5)) break;
+ posImportFlag = lookingForDATA + 5;
+ }
+ fImportFlag = (int)posImportFlag;
+ return fImportFlag;
+}
+
+
+
+/*
+ *----------------------------------------------------------------------
+* DumpExternalsObjects --
+*
+* Dumps a COFF symbol table from an EXE or OBJ. We only use
+* it to dump tables from OBJs.
+*----------------------------------------------------------------------
+*/
+void
+DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders,
+ FILE *fout, unsigned cSymbols, int fort)
+{
+ unsigned i;
+ PSTR stringTable;
+ std::string symbol;
+ DWORD SectChar;
+ static int fImportFlag = -1; /* The status is nor defined yet */
+
+ /*
+ * The string table apparently starts right after the symbol table
+ */
+ stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+ for ( i=0; i < cSymbols; i++ ) {
+ if (pSymbolTable->SectionNumber > 0 && ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
+ if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+ /*
+ * The name of the Function entry points
+ */
+ if (pSymbolTable->N.Name.Short != 0) {
+ symbol = "";
+ symbol.insert(0, (const char *)pSymbolTable->N.ShortName, 8);
+ } else {
+ symbol = stringTable + pSymbolTable->N.Name.Long;
+ }
+
+ while (isspace(symbol[0])) symbol.erase(0,1);
+#ifdef _MSC_VER
+ if (symbol[0] == '_') symbol.erase(0,1);
+ if (fort) {
+ std::string::size_type posAt = symbol.find('@');
+ if (posAt != std::string::npos) symbol.erase(posAt);
+ }
+#endif
+ if (fImportFlag) {
+ fImportFlag = 0;
+ fprintf(fout,"EXPORTS \n");
+ }
+ /*
+ Check whether it is "Scalar deleting destructor" and
+ "Vector deleting destructor"
+ */
+ /*
+ if (!strstr(s,"@@UAEPAXI@Z") && !strstr(s,"@@QAEPAXI@Z") &&
+ !strstr(s,"@AEPAXI@Z") && !strstr(s,"AEPAXI@Z") &&
+ !strstr(s,"real@"))
+ */
+ const char *scalarPrefix = "??_G";
+ const char *vectorPrefix = "??_E";
+ if (symbol.compare(0, 4, scalarPrefix) &&
+ symbol.compare(0, 4, vectorPrefix) &&
+ symbol.find("real@") == std::string::npos)
+ {
+ SectChar = pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
+ if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) {
+ // Read only (i.e. constants) must be excluded
+ fprintf(fout, "\t%s \t DATA\n", symbol.c_str());
+ } else {
+ if ( pSymbolTable->Type || !(SectChar & IMAGE_SCN_MEM_READ)) {
+ fprintf(fout, "\t%s\n", symbol.c_str());
+ } else {
+ // printf(" strange symbol: %s \n",s);
+ }
+ }
+ }
+ }
+ }
+ else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED && !pSymbolTable->Type && 0){
+ /*
+ * The IMPORT global variable entry points
+ */
+ if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+ symbol = stringTable + pSymbolTable->N.Name.Long;
+ while (isspace(symbol[0])) symbol.erase(0,1);
+ if (symbol[0] == '_') symbol.erase(0,1);
+ if (!fImportFlag) {
+ fImportFlag = 1;
+ fprintf(fout,"IMPORTS \n");
+ }
+ fprintf(fout, "\t%s DATA \n", symbol.c_str()+1);
+ }
+ }
+
+ /*
+ * Take into account any aux symbols
+ */
+ i += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+ pSymbolTable++;
+ }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpObjFile --
+*
+* Dump an object file--either a full listing or just the exported
+* symbols.
+*----------------------------------------------------------------------
+*/
+void
+DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full, int fort)
+{
+ PIMAGE_SYMBOL PCOFFSymbolTable;
+ PIMAGE_SECTION_HEADER PCOFFSectionHeaders;
+ DWORD_PTR COFFSymbolCount;
+
+ PCOFFSymbolTable = (PIMAGE_SYMBOL)
+ ((DWORD_PTR)pImageFileHeader + pImageFileHeader->PointerToSymbolTable);
+ COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
+
+ PCOFFSectionHeaders = (PIMAGE_SECTION_HEADER)
+ ((DWORD_PTR)pImageFileHeader +
+ IMAGE_SIZEOF_FILE_HEADER +
+ pImageFileHeader->SizeOfOptionalHeader);
+
+
+ if (full) {
+ DumpSymbolTable(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount);
+ } else {
+ int haveExports = HaveExportedObjects(pImageFileHeader, PCOFFSectionHeaders, fout);
+ if (!haveExports)
+ DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount, fort);
+ }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpFile --
+*
+* Open up a file, memory map it, and call the appropriate
+* dumping routine
+*----------------------------------------------------------------------
+*/
+void
+DumpFile(LPSTR filename, FILE *fout, int full, int fort)
+{
+ HANDLE hFile;
+ HANDLE hFileMapping;
+ LPVOID lpFileBase;
+ PIMAGE_DOS_HEADER dosHeader;
+
+ hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ fprintf(stderr, "Couldn't open file with CreateFile()\n");
+ return;
+ }
+
+ hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (hFileMapping == 0) {
+ CloseHandle(hFile);
+ fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
+ return;
+ }
+
+ lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
+ if (lpFileBase == 0) {
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+ fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
+ return;
+ }
+
+ dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
+ if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
+#if 0
+ DumpExeFile( dosHeader );
+#else
+ fprintf(stderr, "File is an executable. I don't dump those.\n");
+ return;
+#endif
+ }
+ /* Does it look like a i386 COFF OBJ file??? */
+ else if (
+ ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) || (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64))
+ && (dosHeader->e_sp == 0)
+ ) {
+ /*
+ * The two tests above aren't what they look like. They're
+ * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
+ * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
+ */
+ DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full, fort);
+ } else {
+ printf("unrecognized file format\n");
+ }
+ UnmapViewOfFile(lpFileBase);
+ CloseHandle(hFileMapping);
+ CloseHandle(hFile);
+}
+
+void
+main(int argc, char **argv)
+{
+ std::string cmdline;
+ int i, arg;
+ FILE *fout;
+ int full = 0;
+ int fort = 0;
+ char *dllname = "";
+ char *outfile = NULL;
+
+ if (argc < 3) {
+Usage:
+ fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
+ exit(1);
+ }
+
+ arg = 1;
+ while (argv[arg][0] == '-') {
+ if (strcmp(argv[arg], "--") == 0) {
+ arg++;
+ break;
+ } else if (strcmp(argv[arg], "-f") == 0) {
+ full = 1;
+ } else if (strcmp(argv[arg], "-x") == 0) {
+ fort = 1;
+ } else if (strcmp(argv[arg], "-o") == 0) {
+ arg++;
+ if (arg == argc) {
+ goto Usage;
+ }
+ outfile = argv[arg];
+ }
+ arg++;
+ }
+ if (arg == argc) {
+ goto Usage;
+ }
+
+ if (outfile) {
+ fout = fopen(outfile, "w+");
+ if (fout == NULL) {
+ fprintf(stderr, "Unable to open \'%s\' for writing:\n",
+ argv[arg]);
+ perror("");
+ exit(1);
+ }
+ } else {
+ fout = stdout;
+ }
+
+ if (! full) {
+ dllname = argv[arg];
+ arg++;
+ if (arg == argc) {
+ goto Usage;
+ }
+ fprintf(fout, "LIBRARY %s\n", dllname);
+#ifndef _X86_
+ fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
+ fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
+#endif
+ }
+
+ for (; arg < argc; arg++) {
+ WIN32_FIND_DATA FindFileData;
+ HANDLE SearchFile;
+ if (argv[arg][0] == '@') {
+ std::ifstream fargs(&argv[arg][1]);
+ if (!fargs) {
+ fprintf(stderr, "Unable to open \'%s\' for reading:\n",
+ argv[arg]);
+ perror("");
+ exit(1);
+ }
+ char *fargv[1000];
+ for (i = 0; i < arg; i++) {
+ cmdline += argv[i];
+ fargv[i] = argv[i];
+ }
+ std::string line;
+ std::getline(fargs, line);
+ cmdline += line;
+ fprintf(stderr, "%s\n", line.c_str());
+ i += GetArgcArgv(line, &fargv[i]);
+ argc = i;
+ argv = fargv;
+ }
+ /*
+ * Argument can contain the wildcard names
+ */
+ SearchFile = FindFirstFile(argv[arg],&FindFileData);
+ if (SearchFile == INVALID_HANDLE_VALUE){
+ fprintf(stderr, "Unable to find \'%s\' for reading:\n",
+ argv[arg]);
+ exit(1);
+ }
+ else {
+ /*
+ * Since WIN32_FIND_DATA has no path information one has to extract it himself.
+ */
+ TCHAR *filename = argv[arg];
+ TCHAR path[2048];
+ size_t i = strlen(filename);
+ i--;
+ while( filename[i] != '\\' && filename[i] != '/' && i >=0) i--;
+ do
+ {
+ if (i >= 0) strncpy( path, filename, i+1); /* Generate the 'path' info */
+ path[i+1] = '\0';
+ DumpFile(strcat(path, FindFileData.cFileName), fout, full, fort);
+ } while (FindNextFile(SearchFile,&FindFileData));
+
+
+ FindClose(SearchFile);
+ }
+ }
+ exit(0);
+}