Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* -------------------------------------------------------------- */
  2. /*
  3.         "tiny_impdef creates a .def file from a dll"
  4.  
  5.         "Usage: tiny_impdef [-p] <library.dll> [-o outputfile]"
  6.         "Options:"
  7.         " -p print to stdout"
  8. */
  9.  
  10. #include <windows.h>
  11. #include <stdio.h>
  12.  
  13. /* Offset to PE file signature                              */
  14. #define NTSIGNATURE(a) ((LPVOID)((BYTE *)a                +  \
  15.                                                 ((PIMAGE_DOS_HEADER)a)->e_lfanew))
  16.  
  17. /* MS-OS header identifies the NT PEFile signature dword;
  18.    the PEFILE header exists just after that dword.           */
  19. #define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a               +  \
  20.                                                  ((PIMAGE_DOS_HEADER)a)->e_lfanew +  \
  21.                                                          SIZE_OF_NT_SIGNATURE))
  22.  
  23. /* PE optional header is immediately after PEFile header.    */
  24. #define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a               +  \
  25.                                                  ((PIMAGE_DOS_HEADER)a)->e_lfanew +  \
  26.                                                    SIZE_OF_NT_SIGNATURE           +  \
  27.                                                    sizeof (IMAGE_FILE_HEADER)))
  28.  
  29. /* Section headers are immediately after PE optional header. */
  30. #define SECHDROFFSET(a) ((LPVOID)((BYTE *)a               +  \
  31.                                                  ((PIMAGE_DOS_HEADER)a)->e_lfanew +  \
  32.                                                    SIZE_OF_NT_SIGNATURE           +  \
  33.                                                    sizeof (IMAGE_FILE_HEADER)     +  \
  34.                                                    sizeof (IMAGE_OPTIONAL_HEADER)))
  35.  
  36.  
  37. #define SIZE_OF_NT_SIGNATURE 4
  38.  
  39. /* -------------------------------------------------------------- */
  40.  
  41. int   WINAPI NumOfSections (
  42.         LPVOID    lpFile)
  43. {
  44.         /* Number of sections is indicated in file header. */
  45.         return (int)
  46.                 ((PIMAGE_FILE_HEADER)
  47.                         PEFHDROFFSET(lpFile))->NumberOfSections;
  48. }
  49.  
  50.  
  51. /* -------------------------------------------------------------- */
  52.  
  53. LPVOID  WINAPI ImageDirectoryOffset (
  54.                 LPVOID    lpFile,
  55.                 DWORD     dwIMAGE_DIRECTORY)
  56. {
  57.         PIMAGE_OPTIONAL_HEADER   poh;
  58.         PIMAGE_SECTION_HEADER    psh;
  59.         int                      nSections = NumOfSections (lpFile);
  60.         int                      i = 0;
  61.         LPVOID                   VAImageDir;
  62.  
  63.         /* Retrieve offsets to optional and section headers. */
  64.         poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
  65.         psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile);
  66.  
  67.         /* Must be 0 thru (NumberOfRvaAndSizes-1). */
  68.         if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
  69.                 return NULL;
  70.  
  71.         /* Locate image directory's relative virtual address. */
  72.         VAImageDir = (LPVOID)poh->DataDirectory
  73.                                            [dwIMAGE_DIRECTORY].VirtualAddress;
  74.  
  75.         /* Locate section containing image directory. */
  76.         while (i++<nSections)
  77.                 {
  78.                 if (psh->VirtualAddress <= (DWORD)VAImageDir
  79.                  && psh->VirtualAddress + psh->SizeOfRawData > (DWORD)VAImageDir)
  80.                         break;
  81.                 psh++;
  82.                 }
  83.  
  84.         if (i > nSections)
  85.                 return NULL;
  86.  
  87.         /* Return image import directory offset. */
  88.         return (LPVOID)(((int)lpFile +
  89.                                          (int)VAImageDir - psh->VirtualAddress) +
  90.                                         (int)psh->PointerToRawData);
  91. }
  92.  
  93. /* -------------------------------------------------------------- */
  94.  
  95. BOOL    WINAPI GetSectionHdrByName (
  96.         LPVOID                   lpFile,
  97.         IMAGE_SECTION_HEADER     *sh,
  98.         char                     *szSection)
  99. {
  100.         PIMAGE_SECTION_HEADER    psh;
  101.         int                      nSections = NumOfSections (lpFile);
  102.         int                      i;
  103.  
  104.         if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) !=
  105.                  NULL)
  106.                 {
  107.                 /* find the section by name */
  108.                 for (i=0; i<nSections; i++)
  109.                         {
  110.                         if (!strcmp (psh->Name, szSection))
  111.                                 {
  112.                                 /* copy data to header */
  113.                                 memcpy ((LPVOID)sh,
  114.                                                         (LPVOID)psh,
  115.                                                         sizeof (IMAGE_SECTION_HEADER));
  116.                                 return TRUE;
  117.                                 }
  118.                         else
  119.                                 psh++;
  120.                         }
  121.                 }
  122.  
  123.         return FALSE;
  124. }
  125.  
  126. /* -------------------------------------------------------------- */
  127.  
  128. BOOL    WINAPI GetSectionHdrByAddress (
  129.         LPVOID                   lpFile,
  130.         IMAGE_SECTION_HEADER     *sh,
  131.         DWORD                    addr)
  132. {
  133.         PIMAGE_SECTION_HEADER    psh;
  134.         int                      nSections = NumOfSections (lpFile);
  135.         int                      i;
  136.  
  137.         if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) !=
  138.                  NULL)
  139.                 {
  140.                 /* find the section by name */
  141.                 for (i=0; i<nSections; i++)
  142.                         {
  143.                         if (addr >= psh->VirtualAddress && addr < psh->VirtualAddress + psh->SizeOfRawData)
  144.                                 {
  145.                                 /* copy data to header */
  146.                                 memcpy ((LPVOID)sh,
  147.                                                         (LPVOID)psh,
  148.                                                         sizeof (IMAGE_SECTION_HEADER));
  149.                                 return TRUE;
  150.                                 }
  151.                         else
  152.                                 psh++;
  153.                         }
  154.                 }
  155.  
  156.         return FALSE;
  157. }
  158.  
  159. /* -------------------------------------------------------------- */
  160.  
  161. int  WINAPI GetExportFunctionNames (
  162.         LPVOID    lpFile,
  163.         HANDLE    hHeap,
  164.         char      **pszFunctions)
  165. {
  166.         IMAGE_SECTION_HEADER       sh;
  167.         PIMAGE_EXPORT_DIRECTORY    ped;
  168.         int                        *pNames, *pCnt;
  169.         char *pSrc, *pDest;
  170.         int                        i, nCnt;
  171.         DWORD                      VAImageDir;
  172.         PIMAGE_OPTIONAL_HEADER     poh;
  173.         char *pOffset;
  174.  
  175.         /* Get section header and pointer to data directory
  176.            for .edata section. */
  177.         if ((ped = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryOffset
  178.                         (lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT)) == NULL)
  179.                 return 0;
  180.  
  181.         poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
  182.         VAImageDir = poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  183.  
  184.         if (FALSE == GetSectionHdrByAddress (lpFile, &sh, VAImageDir)) return 0;
  185.  
  186.         pOffset = (char *)lpFile + (sh.PointerToRawData -  sh.VirtualAddress);
  187.  
  188.         pNames = (int *)(pOffset + (DWORD)ped->AddressOfNames);
  189.  
  190.         /* Figure out how much memory to allocate for all strings. */
  191.         nCnt = 1;
  192.         for (i=0, pCnt = pNames; i<(int)ped->NumberOfNames; i++)
  193.         {
  194.            pSrc = (pOffset + *pCnt++);
  195.            if (pSrc) nCnt += strlen(pSrc)+1;
  196.         }
  197.  
  198.         /* Allocate memory off heap for function names. */
  199.         pDest = *pszFunctions = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nCnt);
  200.  
  201.         /* Copy all strings to buffer. */
  202.         for (i=0, pCnt = pNames; i<(int)ped->NumberOfNames; i++)
  203.         {
  204.            pSrc = (pOffset + *pCnt++);
  205.            if (pSrc) { strcpy(pDest, pSrc); pDest += strlen(pSrc)+1; }
  206.         }
  207.         *pDest = 0;
  208.  
  209.         return ped->NumberOfNames;
  210. }
  211.  
  212. /* -------------------------------------------------------------- */
  213.  
  214. int main(int argc, char **argv)
  215. {
  216.  
  217.         HANDLE hHeap; HANDLE hFile; HANDLE hMapObject; VOID *pMem;
  218.         int nCnt, ret, argind, std;
  219.         char *pNames;
  220.         char infile[MAX_PATH];
  221.         char buffer[MAX_PATH];
  222.         char outfile[MAX_PATH];
  223.         char libname[80];
  224.  
  225.         hHeap = NULL;
  226.         hFile = NULL;
  227.         hMapObject = NULL;
  228.         pMem = NULL;
  229.         infile[0] = 0;
  230.         outfile[0] = 0;
  231.         ret = 0;
  232.         std = 0;
  233.  
  234.         for (argind = 1; argind < argc; ++argind)
  235.         {
  236.                 const char *a = argv[argind];
  237.                 if ('-' == a[0])
  238.                 {
  239.                         if (0 == strcmp(a, "-p"))
  240.                                 std = 1;
  241.                         else
  242.                         if (0 == strcmp(a, "-o"))
  243.                         {
  244.                                 if (++argind == argc) goto usage;
  245.                                 strcpy(outfile, argv[argind]);
  246.                         }
  247.                         else
  248.                                 goto usage;
  249.                 }
  250.                 else
  251.                 if (0 == infile[0])
  252.                         strcpy(infile, a);
  253.                 else
  254.                         goto usage;
  255.         }
  256.  
  257.         if (0 == infile[0])
  258.         {
  259. usage:
  260.                 fprintf(stderr,
  261.                         "tiny_impdef creates a .def file from a dll\n"
  262.                         "Usage: tiny_impdef [-p] <library.dll> [-o outputfile]\n"
  263.                         "Options:\n"
  264.                         " -p print to stdout\n"
  265.                         );
  266. error:
  267.                 ret = 1;
  268.                 goto the_end;
  269.         }
  270.  
  271.         if (SearchPath(NULL, infile, ".dll", sizeof buffer, buffer, NULL))
  272.                 strcpy(infile, buffer);
  273.  
  274.         if (0 == outfile[0])
  275.         {
  276.                 char *p;
  277.                 p = strrchr(strcpy(outfile, infile), '\\');
  278.                 if (NULL == p)
  279.                 p = strrchr(outfile, '/');
  280.                 if (p) strcpy(outfile, p+1);
  281.  
  282.                 p = strrchr(outfile, '.');
  283.                 if (NULL == p) p = strchr(outfile, 0);
  284.                 strcpy(p, ".def");
  285.         }
  286.  
  287.         hFile=CreateFile(
  288.                 infile,
  289.                 GENERIC_READ,
  290.                 FILE_SHARE_READ,
  291.                 NULL,
  292.                 OPEN_EXISTING,
  293.                 0,
  294.                 NULL
  295.                 );
  296.  
  297.         if (hFile == INVALID_HANDLE_VALUE)
  298.         {
  299.                 fprintf(stderr, "file not found: %s\n", infile);
  300.                 goto error;
  301.         }
  302.  
  303.         if (!std) printf("--> %s\n", infile);
  304.  
  305.         hMapObject = CreateFileMapping(
  306.                 hFile,
  307.                 NULL,
  308.                 PAGE_READONLY,
  309.                 0, 0,
  310.                 NULL
  311.                 );
  312.  
  313.         if (NULL == hMapObject)
  314.         {
  315.                 fprintf(stderr, "could not create file mapping.\n");
  316.                 goto error;
  317.         }
  318.  
  319.         pMem = MapViewOfFile(
  320.                 hMapObject,     // object to map view of
  321.                 FILE_MAP_READ,  // read access
  322.                 0,              // high offset:  map from
  323.                 0,              // low offset:   beginning
  324.                 0);             // default: map entire file
  325.  
  326.         if (NULL == pMem)
  327.         {
  328.                 fprintf(stderr, "could not map view of file.\n");
  329.                 goto error;
  330.         }
  331.  
  332.         hHeap = GetProcessHeap();
  333.         nCnt = GetExportFunctionNames(pMem, hHeap, &pNames);
  334.         {
  335.                 FILE *op; char *p; int n;
  336.                 if (!std) printf("<-- %s\n", outfile);
  337.  
  338.                 if (std)
  339.                         op = stdout;
  340.                 else
  341.                         op = fopen(outfile, "wt");
  342.  
  343.                 if (NULL == op)
  344.                 {
  345.                         fprintf(stderr, "could not create file: %s\n", outfile);
  346.                         goto error;
  347.                 }
  348.  
  349.                 p = strrchr(infile, '\\');
  350.                 if (NULL == p)
  351.                 p = strrchr(infile, '/');
  352.                 if (NULL == p) p = infile; else ++p;
  353.  
  354.                 fprintf(op, "LIBRARY %s\n\nEXPORTS", p);
  355.                 if (std) fprintf(op, " (%d)", nCnt);
  356.                 fprintf(op, "\n");
  357.                 for (n = 0, p = pNames; n < nCnt; ++n)
  358.                 {
  359.                         fprintf(op, "%s\n", p);
  360.                         while (*p++);
  361.                 }
  362.                 if (!std) fclose(op);
  363.         }
  364.  
  365. the_end:
  366.         if (pMem) UnmapViewOfFile(pMem);
  367.         if (hMapObject) CloseHandle(hMapObject);
  368.         if (hFile) CloseHandle(hFile);
  369.         return ret;
  370. }
  371. /* -------------------------------------------------------------- */
  372.  
  373.