kolibrios/programs/develop/ktcc/trunk/source/tiny_impdef.c
andrew_programmer 16f5992719 Mistakes in functions of work with files and with system calls KolibriOS are corrected.
New functions for work with system calls KolibriOS are added. Functions for format output 
are added: printf (), fprintf (), sprintf (), snprintf (), vsnprintf (). For material 
numbers it is meanwhile supported only format output the (%f), and exponential output a (%e)
is not realized yet. 
Functions for format output correctly work only in GCC because TinyC incorrectly works with
the functions containing variable number of arguments.

git-svn-id: svn://kolibrios.org@647 a494cfbc-eb01-0410-851d-a64ba20cac60
2007-10-15 09:42:17 +00:00

373 lines
8.9 KiB
C

/* -------------------------------------------------------------- */
/*
"tiny_impdef creates a .def file from a dll"
"Usage: tiny_impdef [-p] <library.dll> [-o outputfile]"
"Options:"
" -p print to stdout"
*/
#include <windows.h>
#include <stdio.h>
/* Offset to PE file signature */
#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew))
/* MS-OS header identifies the NT PEFile signature dword;
the PEFILE header exists just after that dword. */
#define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew + \
SIZE_OF_NT_SIGNATURE))
/* PE optional header is immediately after PEFile header. */
#define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew + \
SIZE_OF_NT_SIGNATURE + \
sizeof (IMAGE_FILE_HEADER)))
/* Section headers are immediately after PE optional header. */
#define SECHDROFFSET(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew + \
SIZE_OF_NT_SIGNATURE + \
sizeof (IMAGE_FILE_HEADER) + \
sizeof (IMAGE_OPTIONAL_HEADER)))
#define SIZE_OF_NT_SIGNATURE 4
/* -------------------------------------------------------------- */
int WINAPI NumOfSections (
LPVOID lpFile)
{
/* Number of sections is indicated in file header. */
return (int)
((PIMAGE_FILE_HEADER)
PEFHDROFFSET(lpFile))->NumberOfSections;
}
/* -------------------------------------------------------------- */
LPVOID WINAPI ImageDirectoryOffset (
LPVOID lpFile,
DWORD dwIMAGE_DIRECTORY)
{
PIMAGE_OPTIONAL_HEADER poh;
PIMAGE_SECTION_HEADER psh;
int nSections = NumOfSections (lpFile);
int i = 0;
LPVOID VAImageDir;
/* Retrieve offsets to optional and section headers. */
poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile);
/* Must be 0 thru (NumberOfRvaAndSizes-1). */
if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
return NULL;
/* Locate image directory's relative virtual address. */
VAImageDir = (LPVOID)poh->DataDirectory
[dwIMAGE_DIRECTORY].VirtualAddress;
/* Locate section containing image directory. */
while (i++<nSections)
{
if (psh->VirtualAddress <= (DWORD)VAImageDir
&& psh->VirtualAddress + psh->SizeOfRawData > (DWORD)VAImageDir)
break;
psh++;
}
if (i > nSections)
return NULL;
/* Return image import directory offset. */
return (LPVOID)(((int)lpFile +
(int)VAImageDir - psh->VirtualAddress) +
(int)psh->PointerToRawData);
}
/* -------------------------------------------------------------- */
BOOL WINAPI GetSectionHdrByName (
LPVOID lpFile,
IMAGE_SECTION_HEADER *sh,
char *szSection)
{
PIMAGE_SECTION_HEADER psh;
int nSections = NumOfSections (lpFile);
int i;
if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) !=
NULL)
{
/* find the section by name */
for (i=0; i<nSections; i++)
{
if (!strcmp (psh->Name, szSection))
{
/* copy data to header */
memcpy ((LPVOID)sh,
(LPVOID)psh,
sizeof (IMAGE_SECTION_HEADER));
return TRUE;
}
else
psh++;
}
}
return FALSE;
}
/* -------------------------------------------------------------- */
BOOL WINAPI GetSectionHdrByAddress (
LPVOID lpFile,
IMAGE_SECTION_HEADER *sh,
DWORD addr)
{
PIMAGE_SECTION_HEADER psh;
int nSections = NumOfSections (lpFile);
int i;
if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) !=
NULL)
{
/* find the section by name */
for (i=0; i<nSections; i++)
{
if (addr >= psh->VirtualAddress && addr < psh->VirtualAddress + psh->SizeOfRawData)
{
/* copy data to header */
memcpy ((LPVOID)sh,
(LPVOID)psh,
sizeof (IMAGE_SECTION_HEADER));
return TRUE;
}
else
psh++;
}
}
return FALSE;
}
/* -------------------------------------------------------------- */
int WINAPI GetExportFunctionNames (
LPVOID lpFile,
HANDLE hHeap,
char **pszFunctions)
{
IMAGE_SECTION_HEADER sh;
PIMAGE_EXPORT_DIRECTORY ped;
int *pNames, *pCnt;
char *pSrc, *pDest;
int i, nCnt;
DWORD VAImageDir;
PIMAGE_OPTIONAL_HEADER poh;
char *pOffset;
/* Get section header and pointer to data directory
for .edata section. */
if ((ped = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryOffset
(lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT)) == NULL)
return 0;
poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
VAImageDir = poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
if (FALSE == GetSectionHdrByAddress (lpFile, &sh, VAImageDir)) return 0;
pOffset = (char *)lpFile + (sh.PointerToRawData - sh.VirtualAddress);
pNames = (int *)(pOffset + (DWORD)ped->AddressOfNames);
/* Figure out how much memory to allocate for all strings. */
nCnt = 1;
for (i=0, pCnt = pNames; i<(int)ped->NumberOfNames; i++)
{
pSrc = (pOffset + *pCnt++);
if (pSrc) nCnt += strlen(pSrc)+1;
}
/* Allocate memory off heap for function names. */
pDest = *pszFunctions = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nCnt);
/* Copy all strings to buffer. */
for (i=0, pCnt = pNames; i<(int)ped->NumberOfNames; i++)
{
pSrc = (pOffset + *pCnt++);
if (pSrc) { strcpy(pDest, pSrc); pDest += strlen(pSrc)+1; }
}
*pDest = 0;
return ped->NumberOfNames;
}
/* -------------------------------------------------------------- */
int main(int argc, char **argv)
{
HANDLE hHeap; HANDLE hFile; HANDLE hMapObject; VOID *pMem;
int nCnt, ret, argind, std;
char *pNames;
char infile[MAX_PATH];
char buffer[MAX_PATH];
char outfile[MAX_PATH];
char libname[80];
hHeap = NULL;
hFile = NULL;
hMapObject = NULL;
pMem = NULL;
infile[0] = 0;
outfile[0] = 0;
ret = 0;
std = 0;
for (argind = 1; argind < argc; ++argind)
{
const char *a = argv[argind];
if ('-' == a[0])
{
if (0 == strcmp(a, "-p"))
std = 1;
else
if (0 == strcmp(a, "-o"))
{
if (++argind == argc) goto usage;
strcpy(outfile, argv[argind]);
}
else
goto usage;
}
else
if (0 == infile[0])
strcpy(infile, a);
else
goto usage;
}
if (0 == infile[0])
{
usage:
fprintf(stderr,
"tiny_impdef creates a .def file from a dll\n"
"Usage: tiny_impdef [-p] <library.dll> [-o outputfile]\n"
"Options:\n"
" -p print to stdout\n"
);
error:
ret = 1;
goto the_end;
}
if (SearchPath(NULL, infile, ".dll", sizeof buffer, buffer, NULL))
strcpy(infile, buffer);
if (0 == outfile[0])
{
char *p;
p = strrchr(strcpy(outfile, infile), '\\');
if (NULL == p)
p = strrchr(outfile, '/');
if (p) strcpy(outfile, p+1);
p = strrchr(outfile, '.');
if (NULL == p) p = strchr(outfile, 0);
strcpy(p, ".def");
}
hFile=CreateFile(
infile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "file not found: %s\n", infile);
goto error;
}
if (!std) printf("--> %s\n", infile);
hMapObject = CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
0, 0,
NULL
);
if (NULL == hMapObject)
{
fprintf(stderr, "could not create file mapping.\n");
goto error;
}
pMem = MapViewOfFile(
hMapObject, // object to map view of
FILE_MAP_READ, // read access
0, // high offset: map from
0, // low offset: beginning
0); // default: map entire file
if (NULL == pMem)
{
fprintf(stderr, "could not map view of file.\n");
goto error;
}
hHeap = GetProcessHeap();
nCnt = GetExportFunctionNames(pMem, hHeap, &pNames);
{
FILE *op; char *p; int n;
if (!std) printf("<-- %s\n", outfile);
if (std)
op = stdout;
else
op = fopen(outfile, "wt");
if (NULL == op)
{
fprintf(stderr, "could not create file: %s\n", outfile);
goto error;
}
p = strrchr(infile, '\\');
if (NULL == p)
p = strrchr(infile, '/');
if (NULL == p) p = infile; else ++p;
fprintf(op, "LIBRARY %s\n\nEXPORTS", p);
if (std) fprintf(op, " (%d)", nCnt);
fprintf(op, "\n");
for (n = 0, p = pNames; n < nCnt; ++n)
{
fprintf(op, "%s\n", p);
while (*p++);
}
if (!std) fclose(op);
}
the_end:
if (pMem) UnmapViewOfFile(pMem);
if (hMapObject) CloseHandle(hMapObject);
if (hFile) CloseHandle(hFile);
return ret;
}
/* -------------------------------------------------------------- */