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

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

Corrections, DB optimizations, and some new features in StateUpd.

File size: 12.4 KB
Line 
1/* $Id: APIImport.cpp,v 1.3 2000-02-12 23:54:28 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(char *pszDemangled, const char *pszMangledName);
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 /* exported name */
289 if (export.achName == '\0')
290 sprintf(&szName[0], "Ordinal%04ld", export.ulOrdinal);
291 else
292 strcpy(&szName[0], &export.achName[0]);
293
294 /* internal name */
295 if (export.achIntName[0] == '\0')
296 demangle(&szIntName[0], &szName[0]);
297 else
298 demangle(&szIntName[0], export.achIntName);
299
300 fprintf(phLog, "%s: %08ld %-30s %s\n",
301 pszFilename, export.ulOrdinal, &szName[0], &szIntName[0]);
302
303 fOk = dbInsertUpdateFunction(sDll,
304 &szName[0],
305 &szIntName[0],
306 export.ulOrdinal,
307 pOptions->fIgnoreOrdinals && export.ulOrdinal != 0xffffffffUL);
308 if (fOk)
309 cFunctions++;
310 }
311
312 if (!fOk)
313 {
314 fprintf(phLog, "%s: error - dbInsertUpdateFunction failed.\n\terror description: %s \n",
315 pszFilename, dbGetLastErrorDesc());
316 lRc = 1;
317 }
318
319 /* next */
320 fOk = pFile->findNextExport(&export);
321 }
322
323 }
324 else
325 fprintf(phLog, "%s: error - could not find/insert module name (%s).\n", pszFilename, pszModuleName);
326 }
327 else
328 fprintf(phLog, "%s: error - could not get module name.\n", pszFilename);
329
330 delete(pFile);
331 }
332 catch (int err)
333 {
334 fprintf(phLog, "%s: error - could not map dll/def into memory, errorno=%d.\n", pszFilename, err);
335 }
336 fclose(phFile);
337 }
338 else
339 fprintf(phLog, "%s: error - could not open file.\n", pszFilename);
340
341 /* close db */
342 dbDisconnect();
343
344 return lRc;
345}
346
347
348/**
349 * Demangles stdcall functions.
350 * @param pszDemangled Pointer to buffer which will hold the demangled name upon return.
351 * @param pszMangledName Mangled name
352 */
353static void demangle(char *pszDemangled, const char *pszMangledName)
354{
355 int iEnd;
356 /* check for @ */
357 iEnd = strlen(pszMangledName);
358 if (iEnd-- > 3 && *pszMangledName == '_')
359 {
360 while ((pszMangledName[iEnd] >= '0' && pszMangledName[iEnd] <= '9') && iEnd > 0)
361 iEnd--;
362 if (pszMangledName[iEnd] == '@')
363 {
364 *pszDemangled = '\0';
365 strncat(pszDemangled, pszMangledName+1, iEnd - 1);
366 return;
367 }
368 }
369
370 /* not stdcall */
371 strcpy(pszDemangled, pszMangledName);
372}
373
Note: See TracBrowser for help on using the repository browser.