Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
145 halyavin 1
/* -------------------------------------------------------------- */
2
/*
3
	"tiny_impdef creates a .def file from a dll"
4
 
5
	"Usage: tiny_impdef [-p]  [-o outputfile]"
6
	"Options:"
7
	" -p print to stdout"
8
*/
9
 
10
#include 
11
#include 
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++
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
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
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]  [-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