1
/* -------------------------------------------------------------- */
3
"tiny_impdef creates a .def file from a dll"
5
"Usage: tiny_impdef [-p] <library.dll> [-o outputfile]"
13
/* Offset to PE file signature */
14
#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + \
15
((PIMAGE_DOS_HEADER)a)->e_lfanew))
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))
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)))
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)))
37
#define SIZE_OF_NT_SIGNATURE 4
39
/* -------------------------------------------------------------- */
41
int WINAPI NumOfSections (
44
/* Number of sections is indicated in file header. */
47
PEFHDROFFSET(lpFile))->NumberOfSections;
51
/* -------------------------------------------------------------- */
53
LPVOID WINAPI ImageDirectoryOffset (
55
DWORD dwIMAGE_DIRECTORY)
57
PIMAGE_OPTIONAL_HEADER poh;
58
PIMAGE_SECTION_HEADER psh;
59
int nSections = NumOfSections (lpFile);
63
/* Retrieve offsets to optional and section headers. */
64
poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
65
psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile);
67
/* Must be 0 thru (NumberOfRvaAndSizes-1). */
68
if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
71
/* Locate image directory's relative virtual address. */
72
VAImageDir = (LPVOID)poh->DataDirectory
73
[dwIMAGE_DIRECTORY].VirtualAddress;
75
/* Locate section containing image directory. */
78
if (psh->VirtualAddress <= (DWORD)VAImageDir
79
&& psh->VirtualAddress + psh->SizeOfRawData > (DWORD)VAImageDir)
87
/* Return image import directory offset. */
88
return (LPVOID)(((int)lpFile +
89
(int)VAImageDir - psh->VirtualAddress) +
90
(int)psh->PointerToRawData);
93
/* -------------------------------------------------------------- */
95
BOOL WINAPI GetSectionHdrByName (
97
IMAGE_SECTION_HEADER *sh,
100
PIMAGE_SECTION_HEADER psh;
101
int nSections = NumOfSections (lpFile);
104
if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) !=
107
/* find the section by name */
108
for (i=0; i<nSections; i++)
110
if (!strcmp (psh->Name, szSection))
112
/* copy data to header */
115
sizeof (IMAGE_SECTION_HEADER));
126
/* -------------------------------------------------------------- */
128
BOOL WINAPI GetSectionHdrByAddress (
130
IMAGE_SECTION_HEADER *sh,
133
PIMAGE_SECTION_HEADER psh;
134
int nSections = NumOfSections (lpFile);
137
if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) !=
140
/* find the section by name */
141
for (i=0; i<nSections; i++)
143
if (addr >= psh->VirtualAddress && addr < psh->VirtualAddress + psh->SizeOfRawData)
145
/* copy data to header */
148
sizeof (IMAGE_SECTION_HEADER));
159
/* -------------------------------------------------------------- */
161
int WINAPI GetExportFunctionNames (
166
IMAGE_SECTION_HEADER sh;
167
PIMAGE_EXPORT_DIRECTORY ped;
172
PIMAGE_OPTIONAL_HEADER poh;
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)
181
poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
182
VAImageDir = poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
184
if (FALSE == GetSectionHdrByAddress (lpFile, &sh, VAImageDir)) return 0;
186
pOffset = (char *)lpFile + (sh.PointerToRawData - sh.VirtualAddress);
188
pNames = (int *)(pOffset + (DWORD)ped->AddressOfNames);
190
/* Figure out how much memory to allocate for all strings. */
192
for (i=0, pCnt = pNames; i<(int)ped->NumberOfNames; i++)
194
pSrc = (pOffset + *pCnt++);
195
if (pSrc) nCnt += strlen(pSrc)+1;
198
/* Allocate memory off heap for function names. */
199
pDest = *pszFunctions = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nCnt);
201
/* Copy all strings to buffer. */
202
for (i=0, pCnt = pNames; i<(int)ped->NumberOfNames; i++)
204
pSrc = (pOffset + *pCnt++);
205
if (pSrc) { strcpy(pDest, pSrc); pDest += strlen(pSrc)+1; }
209
return ped->NumberOfNames;
212
/* -------------------------------------------------------------- */
214
int main(int argc, char **argv)
217
HANDLE hHeap; HANDLE hFile; HANDLE hMapObject; VOID *pMem;
218
int nCnt, ret, argind, std;
220
char infile[MAX_PATH];
221
char buffer[MAX_PATH];
222
char outfile[MAX_PATH];
234
for (argind = 1; argind < argc; ++argind)
236
const char *a = argv[argind];
239
if (0 == strcmp(a, "-p"))
242
if (0 == strcmp(a, "-o"))
244
if (++argind == argc) goto usage;
245
strcpy(outfile, argv[argind]);
261
"tiny_impdef creates a .def file from a dll\n"
262
"Usage: tiny_impdef [-p] <library.dll> [-o outputfile]\n"
264
" -p print to stdout\n"
271
if (SearchPath(NULL, infile, ".dll", sizeof buffer, buffer, NULL))
272
strcpy(infile, buffer);
277
p = strrchr(strcpy(outfile, infile), '\\');
279
p = strrchr(outfile, '/');
280
if (p) strcpy(outfile, p+1);
282
p = strrchr(outfile, '.');
283
if (NULL == p) p = strchr(outfile, 0);
297
if (hFile == INVALID_HANDLE_VALUE)
299
fprintf(stderr, "file not found: %s\n", infile);
303
if (!std) printf("--> %s\n", infile);
305
hMapObject = CreateFileMapping(
313
if (NULL == hMapObject)
315
fprintf(stderr, "could not create file mapping.\n");
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
328
fprintf(stderr, "could not map view of file.\n");
332
hHeap = GetProcessHeap();
333
nCnt = GetExportFunctionNames(pMem, hHeap, &pNames);
335
FILE *op; char *p; int n;
336
if (!std) printf("<-- %s\n", outfile);
341
op = fopen(outfile, "wt");
345
fprintf(stderr, "could not create file: %s\n", outfile);
349
p = strrchr(infile, '\\');
351
p = strrchr(infile, '/');
352
if (NULL == p) p = infile; else ++p;
354
fprintf(op, "LIBRARY %s\n\nEXPORTS", p);
355
if (std) fprintf(op, " (%d)", nCnt);
357
for (n = 0, p = pNames; n < nCnt; ++n)
359
fprintf(op, "%s\n", p);
362
if (!std) fclose(op);
366
if (pMem) UnmapViewOfFile(pMem);
367
if (hMapObject) CloseHandle(hMapObject);
368
if (hFile) CloseHandle(hFile);
371
/* -------------------------------------------------------------- */