source: trunk/tools/database/APIImport.cpp

Last change on this file was 8019, checked in by bird, 24 years ago

Corrected the catch statments

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