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 /* -------------------------------------------------------------- */