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

Last change on this file since 4712 was 4618, checked in by bird, 25 years ago

kFileDef has changed parameters.
kfilePe has not - temporary disabled.

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