source: trunk/tools/database/APIImport.cpp@ 2759

Last change on this file since 2759 was 2759, checked in by bird, 26 years ago

Odin32 DB.

File size: 12.1 KB
Line 
1/* $Id: APIImport.cpp,v 1.2 2000-02-11 18:35:53 bird Exp $ */
2/*
3 *
4 * APIImport - imports a DLL or Dll-.def with functions into the Odin32 database.
5 *
6 * Copyright (c) 1999-2000 knut st. osmundsen
7 *
8 */
9
10
11/*******************************************************************************
12* Header Files *
13*******************************************************************************/
14#include <os2.h>
15#include <stdio.h>
16#include <string.h>
17
18#include "APIImport.h"
19#include "kFileFormatBase.h"
20#include "kFilePE.h"
21#include "kFileDef.h"
22#include "db.h"
23
24
25/*******************************************************************************
26* Global Variables *
27*******************************************************************************/
28static FILE *phLog = NULL;
29
30/*******************************************************************************
31* Internal Functions *
32*******************************************************************************/
33static void syntax(void);
34static void openLog(void);
35static void closeLog(void);
36static long processFile(const char *pszFilename, const POPTIONS pOptions, long &cFunctions);
37static void demangle(const char *pszMangledName, char *pszDemangled);
38
39
40/**
41 * Main function.
42 * @returns low word : number of errors
43 * high word: flags.
44 * @param argc Argument count.
45 * @param argv Argument array.
46 */
47int main(int argc, char **argv)
48{
49 int argi;
50 BOOL fFatal = FALSE;
51 long lRc = 0;
52 OPTIONS options = {0};
53 char *pszHost = "localhost";
54 char *pszDatabase = "Odin32";
55 char *pszUser = "root";
56 char *pszPasswd = "";
57 long cFunctions = 0;
58
59
60 /**************************************************************************
61 * parse arguments.
62 * options: -h or -? help
63 * -o[+|-] ordinals, o- ignore them, o+ import them (def).
64 * -d:<dbname> Database name
65 * -p:<passwd> Password
66 * -u:<user> Userid
67 * -h:<host> Hostname/IP-address
68 **************************************************************************/
69 if (argc == 1)
70 syntax();
71 argi = 1;
72 while (argi < argc && !fFatal)
73 {
74 if(argv[argi][0] == '-' || argv[argi][0] == '/')
75 {
76 switch (argv[argi][1])
77 {
78 case 'd':
79 case 'D':
80 if (argv[argi][2] == ':')
81 pszDatabase = &argv[argi][3];
82 else
83 fprintf(stderr, "warning: option '-d:' requires database name.\n");
84 break;
85
86 case 'h':
87 case 'H':
88 if (argv[argi][2] == ':')
89 {
90 pszHost = &argv[argi][3];
91 break;
92 }
93 case '?':
94 syntax();
95 return 0;
96
97 case 'o': /* ordinals*/
98 case 'O':
99 options.fIgnoreOrdinals = argv[argi][2] != '-';
100 break;
101
102 case 'p':
103 case 'P':
104 if (argv[argi][2] == ':')
105 pszPasswd = &argv[argi][3];
106 else
107 fprintf(stderr, "warning: option '-p:' requires password.\n");
108 break;
109
110 case 'u':
111 case 'U':
112 if (argv[argi][2] == ':')
113 pszUser = &argv[argi][3];
114 else
115 fprintf(stderr, "error: option '-u:' requires userid.\n");
116 break;
117
118 default:
119 fprintf(stderr, "incorrect parameter. (argi=%d, argv[argi]=%s)\n", argi, argv[argi]);
120 fFatal = TRUE;
121 break;
122 }
123 }
124 else
125 {
126 long l;
127 if (phLog == NULL)
128 openLog();
129 /* try connect to db */
130 if (dbConnect(pszHost, pszUser, pszPasswd, pszDatabase))
131 {
132 l = processFile(argv[argi], &options, cFunctions);
133 lRc = ((lRc & 0xffff0000UL) | (l & 0xffff0000UL)) | ((lRc & 0x0000ffffUL) + l & 0x0000ffffUL);
134 dbDisconnect();
135 }
136 else
137 {
138 fprintf(phLog, "Could not connect to database (Odin32). \n\terror description: %s\n", dbGetLastErrorDesc());
139 l = 0x00010001;
140 lRc = ((lRc & 0xffff0000UL) | (l & 0xffff0000UL)) | ((lRc & 0x0000ffffUL) + l & 0x0000ffffUL);
141 break;
142 }
143 }
144 argi++;
145 }
146
147 /* write function count */
148 if (phLog != NULL)
149 fprintf(phLog, "\n %d functions were imported!\n\n", cFunctions);
150
151 /* close the log */
152 closeLog();
153
154 /* warn if error during processing. */
155 if (!fFatal && lRc > 0)
156 fprintf(stderr, "%s did occur during the processing. Please check the log file. lRc=0x%08lx\n",
157 (0x0000FFFFL & lRc) > 1 ? "Errors" : "An error", lRc);
158 return (int)lRc;
159}
160
161
162
163/**
164 * Display syntax/help .
165 */
166static void syntax()
167{
168 printf("\n"
169 "APIImport v%01d.%02d - Odin32 API Database utility\n"
170 "----------------------------------------------\n"
171 "syntax: APIImport.exe [-h|-?] [options] <dll/defnames>\n"
172 "\n"
173 " -h or -? Syntax help. (this)\n"
174 " -o[+|-] Ordinals, '+' imports (default), '-' ignores.\n"
175 " -h:<hostname> Database server hostname. default: localhost\n"
176 " -u:<username> Username on the server. default: root\n"
177 " -p:<password> Password. default: <empty>\n"
178 " -d:<database> Database to use. default: Odin32\n"
179 " dll/defnames List of DLL/Defs to process.\n"
180 "\n"
181 "Note. Options may be switched on and off between dlls.\n"
182 "\n"
183 "\n"
184 "This utility will insert or update the 'dll' and 'function' tables in the\n"
185 "database. It read a PE-DLL or a OS/2 Definition file (.Def). From the file\n"
186 "it imports the:\n"
187 "\t1) module name\n"
188 "\t2) function name\n"
189 "\t3) function ordinal (If not option 'o-' is specified.)\n"
190 "This utililty is not destructive but additive. That is, it would not remove any\n"
191 "rows in the database, only add or update them. On existing functions the\n"
192 "ordinal value will be updated when 'o+' is specified.\n"
193 "\n"
194 "Copyright (c) 1999 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)",
195 MAJOR_VER, MINOR_VER
196 );
197}
198
199
200/**
201 * Opens the log file.
202 * @remark If open fails stderr is used.
203 */
204static void openLog(void)
205{
206 if (phLog == NULL)
207 {
208 phLog = fopen("APIImport.Log", "w");
209 if (phLog == NULL)
210 {
211 fprintf(stderr,"error occured while opening log file - will use stderr instead.\n");
212 phLog = stderr;
213 }
214 }
215}
216
217
218/**
219 * Closes log file.
220 */
221static void closeLog(void)
222{
223 if (phLog != stderr && phLog != NULL)
224 fclose(phLog);
225}
226
227
228/**
229 * Processes a file using the given options. Transparently processes .Def's and PE DLLs
230 * @returns low word, number of errors.
231 * high word, flags (currently not flags are defined/used).
232 * @param pszFilename Pointer to the filename of the file which is to be processed.
233 * @param pOptions Pointer to the options-struct.
234 * @param cFunctions Function count which is to be updated when functions are imported.
235 */
236static long processFile(const char *pszFilename, const POPTIONS pOptions, long &cFunctions)
237{
238 kFileFormatBase *pFile;
239 FILE *phFile;
240 long lRc = 1;
241
242 /* try open file */
243 phFile = fopen(pszFilename, "rb");
244 if (phFile != NULL)
245 {
246 try
247 {
248 char achDataBuffer[0x200];
249 char *pszModuleName = &achDataBuffer[0];
250 signed short sDll;
251
252 /* try create file objects */
253 try
254 {
255 pFile = new kFilePE(phFile);
256 }
257 catch (int i)
258 {
259 i = i;
260 pFile = new kFileDef(phFile);
261 }
262
263 if (pFile->queryModuleName(pszModuleName))
264 {
265 int cch = strlen(pszModuleName);
266
267 /* remove '.dll' */
268 if (cch > 4 && !stricmp(&pszModuleName[cch-4], ".dll"))
269 pszModuleName[cch-4] = '\0';
270 fprintf(phLog, "%s: modulename = %s\n", pszFilename, pszModuleName);
271
272 /* find or insert module name */
273 if ((sDll = dbCheckInsertDll(pszModuleName)) >= 0)
274 {
275 BOOL fOk;
276 EXPORTENTRY export;
277
278 lRc = 0;
279 fOk = pFile->findFirstExport(&export);
280 while (fOk)
281 {
282 /* check if name or not */
283 if (!pFile->isDef() || export.ulOrdinal < ORD_START_INTERNAL_FUNCTIONS)
284 {
285 char szIntName[64];
286 char szName[64];
287
288 demangle(export.achIntName, &szIntName[0]);
289 if (export.achName == '\0')
290 sprintf(&szName[0], "Ordinal%04ld", export.ulOrdinal);
291 else
292 strcpy(&szName[0], &export.achName[0]);
293
294 fprintf(phLog, "%s: %08ld %-30s %s\n",
295 pszFilename, export.ulOrdinal, &szName[0], &szIntName[0]);
296
297 fOk = dbInsertUpdateFunction(sDll,
298 &szName[0],
299 &szIntName[0],
300 export.ulOrdinal,
301 pOptions->fIgnoreOrdinals && export.ulOrdinal != 0xffffffffUL);
302 if (fOk)
303 cFunctions++;
304 }
305
306 if (!fOk)
307 {
308 fprintf(phLog, "%s: error - dbInsertUpdateFunction failed.\n\terror description: %s \n",
309 pszFilename, dbGetLastErrorDesc());
310 lRc = 1;
311 }
312
313 /* next */
314 fOk = pFile->findNextExport(&export);
315 }
316
317 }
318 else
319 fprintf(phLog, "%s: error - could not find/insert module name (%s).\n", pszFilename, pszModuleName);
320 }
321 else
322 fprintf(phLog, "%s: error - could not get module name.\n", pszFilename);
323
324 delete(pFile);
325 }
326 catch (int err)
327 {
328 fprintf(phLog, "%s: error - could not map dll/def into memory, errorno=%d.\n", pszFilename, err);
329 }
330 fclose(phFile);
331 }
332 else
333 fprintf(phLog, "%s: error - could not open file.\n", pszFilename);
334
335 /* close db */
336 dbDisconnect();
337
338 return lRc;
339}
340
341
342/**
343 * Demangles stdcall functions.
344 * @param pszMangledName Mangled name
345 * @param pszDemangled Pointer to buffer which will hold the demangled name upon return.
346 */
347static void demangle(const char *pszMangledName, char *pszDemangled)
348{
349 int iEnd;
350 /* check for @ */
351 iEnd = strlen(pszMangledName);
352 if (iEnd-- > 3 && *pszMangledName == '_')
353 {
354 while ((pszMangledName[iEnd] >= '0' && pszMangledName[iEnd] <= '9') && iEnd > 0)
355 iEnd--;
356 if (pszMangledName[iEnd] == '@')
357 {
358 *pszDemangled = '\0';
359 strncat(pszDemangled, pszMangledName+1, iEnd - 1);
360 return;
361 }
362 }
363
364 /* not stdcall */
365 strcpy(pszDemangled, pszMangledName);
366}
367
Note: See TracBrowser for help on using the repository browser.