source: trunk/src/win32k/dev16/probkrnl.c@ 4606

Last change on this file since 4606 was 4542, checked in by bird, 25 years ago

Fixed bug which prevented the symbolname to be copied to the szSymbolfile
global variable.

File size: 43.4 KB
Line 
1/* $Id: probkrnl.c,v 1.28 2000-10-27 10:59:13 bird Exp $
2 *
3 * Description: Autoprobes the os2krnl file and os2krnl[*].sym files.
4 * Another Hack!
5 *
6 * 16-bit inittime code.
7 *
8 * All data has to be initiated because this is 16-bit C code
9 * and is to be linked with 32-bit C/C++ code. Uninitiazlied
10 * data ends up in the BSS segment, and that segment can't
11 * both be 32-bit and 16-bit. I have not found any other way
12 * around this problem that initiating all data.
13 *
14 * How this works:
15 * 1. parses the device-line parameters and collects some "SysInfo".
16 * 2. gets the kernel object table and kernel info like build no. (elf$)
17 * 3. if non-debug kernel the symbol database is scanned to get the syms
18 * 4. if Syms not found THEN locates and scans the symbol-file(s) for the
19 * entrypoints which are wanted.
20 * 5. the entry points are verified. (elf$)
21 * 6. finished.
22 *
23 * Copyright (c) 1998-2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
24 *
25 * Project Odin Software License can be found in LICENSE.TXT
26 *
27 */
28
29
30/*******************************************************************************
31* Defined Constants And Macros *
32*******************************************************************************/
33/* Disable logging when doing extracts */
34#if defined(EXTRACT) || defined(RING0)
35 #define NOLOGGING 1
36#endif
37
38#define fclose(a) DosClose(a)
39#define SEEK_SET FILE_BEGIN
40#define SEEK_END FILE_END
41
42#define WORD unsigned short int
43#define DWORD unsigned long int
44
45/* "@#IBM:14.039#@ os2krnl... "*/
46/* "@#IBM:8.264#@ os2krnl... "*/
47#define KERNEL_ID_STRING_LENGTH 42
48#define KERNEL_READ_SIZE 512
49
50#define INCL_BASE
51#define INCL_DOS
52#define INCL_NOPMAPI
53
54/*******************************************************************************
55* Header Files *
56*******************************************************************************/
57#include <os2.h>
58
59#include <exe386.h>
60#include <strat2.h>
61#include <reqpkt.h>
62
63#include "devSegDf.h"
64#undef DATA16_INIT
65#define DATA16_INIT
66#undef CODE16_INIT
67#define CODE16_INIT
68#include "os2krnl.h" /* must be included before dev1632.h! */
69#include "sym.h"
70#include "probkrnl.h"
71#include "dev16.h"
72#include "dev1632.h"
73#include "vprntf16.h"
74#include "log.h"
75#include "options.h"
76#include "errors.h"
77
78/*******************************************************************************
79* Global Variables *
80* Note: must be inited or else we'll get BSS segment *
81*******************************************************************************/
82
83
84/*
85 * aImportTab defines the imported and overloaded OS/2 kernel functions.
86 * IMPORTANT: aImportTab has three sibling arrays, two in dev32\d32init.c (aulProc
87 * and aTstFakers), and the calltab.asm, which must match entry by entry.
88 * - obsolete warning -
89 * When adding/removing/shuffling items in aImportTab, aulProc and
90 * calltab.asm has to be updated immediately!
91 * Use the mkcalltab.exe to generate calltab.asm and aTstFakers.
92 * - obsolete warning -
93 * We'll now generate both of these files from this table.
94 *
95 */
96IMPORTKRNLSYM DATA16_GLOBAL aImportTab[NBR_OF_KRNLIMPORTS] =
97{/* iFound cchName offObject usSel fType */
98 /* iObject achName achExtra ulAddress cProlog */
99 /* Overrides */
100 {FALSE, -1, 12, "_ldrOpenPath", "@20", -1, -1, -1, -1, EPT_PROC32 | EPT_WRAPPED}, /* Must be [0]! See importTabInit. */
101 {FALSE, -1, 8, "_ldrRead", "@24", -1, -1, -1, -1, EPT_PROC32},
102 {FALSE, -1, 8, "_ldrOpen", "@12", -1, -1, -1, -1, EPT_PROC32},
103 {FALSE, -1, 9, "_ldrClose", "@4", -1, -1, -1, -1, EPT_PROC32},
104 {FALSE, -1, 12, "_LDRQAppType", "@8", -1, -1, -1, -1, EPT_PROC32},
105 {FALSE, -1, 20, "_ldrEnum32bitRelRecs", "@24", -1, -1, -1, -1, EPT_PROC32},
106 {FALSE, -1, 11, "g_tkExecPgm", "", -1, -1, -1, -1, EPT_PROC32},
107 {FALSE, -1, 15, "_tkStartProcess", "", -1, -1, -1, -1, EPT_PROC32},
108 {FALSE, -1, 12, "_LDRClearSem", "@0", -1, -1, -1, -1, EPT_PROCIMPORT32},
109 {FALSE, -1, 21, "_ldrASMpMTEFromHandle","@4", -1, -1, -1, -1, EPT_PROCIMPORT32},
110 {FALSE, -1, 14, "_ldrFindModule", "@16", -1, -1, -1, -1, EPT_PROCIMPORT32},
111 {FALSE, -1, 21, "_ldrValidateMteHandle","@4", -1, -1, -1, -1, EPT_PROCIMPORT32},
112 {FALSE, -1, 11, "_VMAllocMem", "@36", -1, -1, -1, -1, EPT_PROCIMPORT32},
113 {FALSE, -1, 10, "_VMFreeMem", "@12", -1, -1, -1, -1, EPT_PROCIMPORT32},
114 {FALSE, -1, 11, "_VMGetOwner", "@8", -1, -1, -1, -1, EPT_PROCIMPORT32},
115 {FALSE, -1, 16, "_VMObjHandleInfo", "@12", -1, -1, -1, -1, EPT_PROCIMPORT32},
116 {FALSE, -1, 16, "_VMMapDebugAlias", "@20", -1, -1, -1, -1, EPT_PROCIMPORT32},
117 {FALSE, -1, 17, "_KSEMRequestMutex", "@8", -1, -1, -1, -1, EPT_PROCIMPORT32},
118 {FALSE, -1, 17, "_KSEMReleaseMutex", "@4", -1, -1, -1, -1, EPT_PROCIMPORT32},
119 {FALSE, -1, 15, "_KSEMQueryMutex", "@8", -1, -1, -1, -1, EPT_PROCIMPORT32},
120 {FALSE, -1, 12, "_TKPidToPTDA", "@8", -1, -1, -1, -1, EPT_PROCIMPORT32},
121 {FALSE, -1, 9, "_TKSuBuff", "@16", -1, -1, -1, -1, EPT_PROCIMPORT32},
122 {FALSE, -1, 9, "_TKFuBuff", "@16", -1, -1, -1, -1, EPT_PROCIMPORT32},
123 {FALSE, -1, 11, "_TKFuBufLen", "@20", -1, -1, -1, -1, EPT_PROCIMPORT32},
124 {FALSE, -1, 11, "_TKSuFuBuff", "@16", -1, -1, -1, -1, EPT_PROCIMPORT32},
125 {FALSE, -1, 11, "f_FuStrLenZ", "", -1, -1, -1, -1, EPT_PROCIMPORT16},
126 {FALSE, -1, 10, "f_FuStrLen", "", -1, -1, -1, -1, EPT_PROCIMPORT16},
127 {FALSE, -1, 8, "f_FuBuff", "", -1, -1, -1, -1, EPT_PROCIMPORT16},
128 {FALSE, -1, 12, "_SftFileSize", "@8", -1, -1, -1, -1, EPT_PROCIMPORT32},
129 {FALSE, -1, 16, "_ldrpFileNameBuf", "", -1, -1, -1, -1, EPT_VARIMPORT32},
130 {FALSE, -1, 7, "_LdrSem", "", -1, -1, -1, -1, EPT_VARIMPORT32},
131 {FALSE, -1, 8, "_pTCBCur", "", -1, -1, -1, -1, EPT_VARIMPORT16},
132 {FALSE, -1, 9, "_pPTDACur", "", -1, -1, -1, -1, EPT_VARIMPORT16},
133 {FALSE, -1, 10, "ptda_start", "", -1, -1, -1, -1, EPT_VARIMPORT16},
134 {FALSE, -1, 12, "ptda_environ", "", -1, -1, -1, -1, EPT_VARIMPORT16},
135 {FALSE, -1, 12, "ptda_ptdasem", "", -1, -1, -1, -1, EPT_VARIMPORT16},
136 {FALSE, -1, 11, "ptda_handle", "", -1, -1, -1, -1, EPT_VARIMPORT16},
137 {FALSE, -1, 11, "ptda_module", "", -1, -1, -1, -1, EPT_VARIMPORT16},
138 {FALSE, -1, 18, "ptda_pBeginLIBPATH", "", -1, -1, -1, -1, EPT_VARIMPORT16},
139 {FALSE, -1, 14, "SecPathFromSFN", "", -1, -1, -1, -1, EPT_PROCIMPORTNR32},
140#if 0 /* not used */
141 {FALSE, -1, 9, "_KSEMInit", "@12", -1, -1, -1, -1, EPT_PROCIMPORT32},
142 {FALSE, -1, 10, "_IOSftOpen", "@20", -1, -1, -1, -1, EPT_PROCIMPORT32},
143 {FALSE, -1, 11, "_IOSftClose", "@4", -1, -1, -1, -1, EPT_PROCIMPORT32},
144 {FALSE, -1, 15, "_IOSftTransPath", "@4", -1, -1, -1, -1, EPT_PROCIMPORT32},
145 {FALSE, -1, 12, "_IOSftReadAt", "@20", -1, -1, -1, -1, EPT_PROCIMPORT32},
146 {FALSE, -1, 13, "_IOSftWriteAt", "@20", -1, -1, -1, -1, EPT_PROCIMPORT32},
147 {FALSE, -1, 11, "_LDRLibPath", "", -1, -1, -1, -1, EPT_VARIMPORT32},
148#endif
149#if 0/* experimenting...*/
150 {FALSE, -1, 14, "_ldrSetVMflags", "@16", -1, -1, -1, -1, EPT_PROC32},
151#endif
152};
153
154/**
155 * szSymbolFile holds the name of the symbol file used.
156 *
157 */
158char DATA16_GLOBAL szSymbolFile[60] = {0};
159
160/**
161 * iProc holds the number of the procedure which failed during verify.
162 */
163int DATA16_GLOBAL iProc = -1; /* The procedure number which failed Verify. */
164
165
166
167/*
168 * privat data
169 */
170static char * DATA16_INIT apszSym[] =
171{
172 {"c:\\os2krnl.sym"}, /* usual for debugkernel */
173 {"c:\\os2\\pdpsi\\pmdf\\warp4\\os2krnlr.sym"}, /* warp 4 */
174 {"c:\\os2\\pdpsi\\pmdf\\warp4\\os2krnld.sym"}, /* warp 4 */
175 {"c:\\os2\\pdpsi\\pmdf\\warp4\\os2krnlb.sym"}, /* warp 4 */
176 {"c:\\os2\\pdpsi\\pmdf\\warp45_u\\os2krnlr.sym"}, /* warp 45 */
177 {"c:\\os2\\pdpsi\\pmdf\\warp45_u\\os2krnld.sym"}, /* warp 45 */
178 {"c:\\os2\\pdpsi\\pmdf\\warp45_u\\os2krnlb.sym"}, /* warp 45 */
179 {"c:\\os2\\pdpsi\\pmdf\\warp45_s\\os2krnlr.sym"}, /* warp 45 */
180 {"c:\\os2\\pdpsi\\pmdf\\warp45_s\\os2krnld.sym"}, /* warp 45 */
181 {"c:\\os2\\pdpsi\\pmdf\\warp45_s\\os2krnlb.sym"}, /* warp 45 */
182 {"c:\\os2\\system\\trace\\os2krnl.sym"}, /* warp 3 ?*/
183 {"c:\\os2\\system\\pmdf\\os2krnlr.sym"}, /* warp 3 ?*/
184 {"c:\\os2krnlr.sym"}, /* custom */
185 {"c:\\os2krnlh.sym"}, /* custom */
186 {"c:\\os2krnld.sym"}, /* custom */
187 NULL
188};
189
190/* Result from GetKernelInfo/ReadOS2Krnl. */
191unsigned char DATA16_INIT cObjects = 0;
192POTE DATA16_INIT paKrnlOTEs = NULL;
193
194
195/*
196 *
197 */
198static struct
199{
200 short sErr;
201 const char *pszMsg;
202} DATA16_INIT aErrorMsgs[] =
203{
204 {ERROR_PROB_KRNL_OPEN_FAILED, "Krnl: Failed to open kernel file."},
205 {ERROR_PROB_KRNL_SEEK_SIZE, "Krnl: Failed to seek to end to of file."},
206 {ERROR_PROB_KRNL_SEEK_FIRST, "Krnl: Failed to start of file."},
207 {ERROR_PROB_KRNL_READ_FIRST, "Krnl: Failed to read (first)."},
208 {ERROR_PROB_KRNL_READ_NEXT, "Krnl: Failed to read."},
209 {ERROR_PROB_KRNL_TAG_NOT_FOUND, "Krnl: Build level tag was not found."},
210 {ERROR_PROB_KRNL_INV_SIGANTURE, "Krnl: Invalid build level signature."},
211 {ERROR_PROB_KRNL_INV_BUILD_NBR, "Krnl: Invalid build level number."},
212 {ERROR_PROB_KRNL_BUILD_VERSION, "Krnl: Invalid build level version."},
213 {ERROR_PROB_KRNL_MZ_SEEK, "Krnl: Failed to seek to start of file. (MZ)"},
214 {ERROR_PROB_KRNL_MZ_READ, "Krnl: Failed to read MZ header."},
215 {ERROR_PROB_KRNL_NEOFF_INVALID, "Krnl: Invalid new-header offset in MZ header."},
216 {ERROR_PROB_KRNL_NEOFF_SEEK, "Krnl: Failed to seek to new-header offset."},
217 {ERROR_PROB_KRNL_LX_READ, "Krnl: Failed to read LX header."},
218 {ERROR_PROB_KRNL_LX_SIGNATURE, "Krnl: Invalid LX header signature."},
219 {ERROR_PROB_KRNL_OBJECT_CNT, "Krnl: Object count don't match the running kernel."},
220 {ERROR_PROB_KRNL_OBJECT_CNR_10, "Krnl: Less than 10 objects - not a valid kernel file!"},
221 {ERROR_PROB_KRNL_OTE_SEEK, "Krnl: Failed to seek to OTEs."},
222 {ERROR_PROB_KRNL_OTE_READ, "Krnl: Failed to read OTEs."},
223 {ERROR_PROB_KRNL_OTE_SIZE_MIS, "Krnl: Size of a OTE didn't match the running kernel."},
224
225 /*
226 * ProbeSymFile error messages + some extra ones.
227 */
228 {ERROR_PROB_SYM_FILE_NOT_FOUND, "Sym: Symbol file was not found."},
229 {ERROR_PROB_SYM_READERROR, "Sym: Read failed."},
230 {ERROR_PROB_SYM_INVALID_MOD_NAME, "Sym: Invalid module name (not OS2KRNL)."},
231 {ERROR_PROB_SYM_SEGS_NE_OBJS, "Sym: Number of segments don't match the object count of the kernel."},
232 {ERROR_PROB_SYM_SEG_DEF_SEEK, "Sym: Failed to seek to a segment definition."},
233 {ERROR_PROB_SYM_SEG_DEF_READ, "Sym: Failed to read a segment definition."},
234 {ERROR_PROB_SYM_IMPORTS_NOTFOUND, "Sym: Some of the imports wasn't found."},
235 {ERROR_PROB_SYM_V_PROC_NOT_FND, "Sym: Verify failed: Procedure not found."},
236 {ERROR_PROB_SYM_V_OBJ_OR_ADDR, "Sym: Verify failed: Invalid object or address."},
237 {ERROR_PROB_SYM_V_ADDRESS, "Sym: Verify failed: Invalid address."},
238 {ERROR_PROB_SYM_V_PROLOG, "Sym: Verify failed: Invalid prolog."},
239 {ERROR_PROB_SYM_V_NOT_IMPL, "Sym: Verify failed: Not implemented."},
240 {ERROR_PROB_SYM_V_GETOS2KRNL, "GetOs2Krnl: failed."},
241 {ERROR_PROB_SYM_V_NO_SWAPMTE, "GetOs2Krnl: No Swap MTE."},
242 {ERROR_PROB_SYM_V_OBJECTS, "GetOs2Krnl: Too many objects."},
243 {ERROR_PROB_SYM_V_OBJECT_TABLE, "GetOs2Krnl: No object table."},
244 {ERROR_PROB_SYM_V_BUILD_INFO, "GetOs2Krnl: Build info not found."},
245 {ERROR_PROB_SYM_V_INVALID_BUILD, "GetOs2Krnl: Unsupported build."},
246 {ERROR_PROB_SYM_V_VERIFY, "importTabInit: Import failed."},
247 {ERROR_PROB_SYM_V_IPE, "importTabInit: Internal-Processing-Error."},
248 {ERROR_PROB_SYM_V_HEAPINIT, "R0Init32: HeapInit Failed."},
249 {ERROR_PROB_SYM_V_D32_LDR_INIT, "R0Init32: ldrInit Failed."},
250
251 {ERROR_PROB_SYMDB_KRNL_NOT_FOUND, "SymDB: Kernel was not found."}
252};
253
254/*
255 * Fake data for Ring-3 testing.
256 */
257#ifdef R3TST
258USHORT DATA16_INIT usFakeVerMajor = 0;
259USHORT DATA16_INIT usFakeVerMinor = 0;
260#ifdef R3TST
261static DATA16_INIT ach[11] = {0}; /* works around compiler/linker bug */
262#endif
263#endif
264
265
266/*******************************************************************************
267* Internal Functions *
268*******************************************************************************/
269/* File an output replacements */
270HFILE fopen(const char * pszFilename, const char * pszIgnored);
271int fread(void * pvBuffer, USHORT cbBlock, USHORT cBlock, HFILE hFile);
272int fseek(HFILE hfile, signed long off, int iOrg);
273unsigned long fsize(HFILE hFile);
274
275/* C-library replacements and additions. */
276void kmemcpy(char *psz1, const char *psz2, int cch);
277char * kstrstr(const char *psz1, const char *psz2);
278int kstrcmp(const char *psz1, const char *psz2);
279int kstrncmp(const char *psz1, const char *psz2, int cch);
280int kstrnicmp(const char *psz1, const char *psz2, int cch);
281int kstrlen(const char *psz);
282char * kstrcpy(char * pszTarget, const char * pszSource);
283int kargncpy(char *pszTarget, const char *pszArg, unsigned cchMaxlen);
284
285/* Workers */
286int LookupKrnlEntry(unsigned short usBuild, unsigned short fKernel, unsigned char cObjects);
287int VerifyPrologs(void);
288int ProbeSymFile(const char *pszFilename);
289int GetKernelInfo(void);
290
291/* Ouput */
292void ShowResult(int rc);
293
294/* Others used while debugging in R3. */
295int VerifyKernelVer(void);
296int ReadOS2Krnl(char *pszFilename);
297int ReadOS2Krnl2(HFILE hKrnl, unsigned long cbKrnl);
298
299
300
301/*******************************************************************************
302* Implementation of Internal Helper Functions *
303*******************************************************************************/
304
305/**
306 * Quick implementation of fopen.
307 * @param pszFilename name of file to open (sz)
308 * @param pszIgnored whatever - it is ignored
309 * @return Handle to file. (not pointer to a FILE stream as in C-library)
310 * @remark binary and readonly is assumed!
311 */
312HFILE fopen(const char * pszFilename, const char * pszIgnored)
313{
314 HFILE hFile = 0;
315 USHORT rc;
316 unsigned short Action = 0;
317
318 rc = DosOpen(
319 (char*)pszFilename,
320 &hFile,
321 &Action,
322 0,
323 FILE_NORMAL,
324 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
325 OPEN_SHARE_DENYNONE + OPEN_ACCESS_READONLY,
326 NULL);
327
328 pszIgnored = pszIgnored;
329 return hFile;
330}
331
332
333/**
334 * fread emulation
335 * @returns Number of blocks read.
336 * @param pvBuffer Buffer to read into
337 * @param cbBlock Blocksize
338 * @param cBlock Block count
339 * @param hFile Handle to file (HFILE)
340 */
341int fread(void * pvBuffer, USHORT cbBlock, USHORT cBlock, HFILE hFile)
342{
343 USHORT ulRead;
344 USHORT rc;
345
346 rc = DosRead(hFile, pvBuffer, (USHORT)(cbBlock*cBlock), &ulRead);
347 if (rc == 0)
348 rc = (USHORT)cBlock;
349 else
350 rc = 0;
351
352 return rc;
353}
354
355
356/**
357 * fseek emultation
358 * @returns Same as DosChgFilePtr
359 * @param hFile Filehandle
360 * @param off offset into file from origin
361 * @param org origin
362 */
363int fseek(HFILE hFile, signed long off, int iOrg)
364{
365 ULONG ul;
366 return (int)DosChgFilePtr(hFile, off, iOrg, &ul);
367}
368
369
370/**
371 * Get filesize in bytes.
372 * @returns Filesize.
373 * @param hFile Filehandle
374 * @remark This function sets the file position to end of file.
375 */
376unsigned long fsize(HFILE hFile)
377{
378 USHORT rc;
379 unsigned long cb;
380
381 rc = DosChgFilePtr(hFile, 0, FILE_END, &cb);
382
383 return cb;
384}
385
386
387/**
388 * kmemcpy - memory copy - slow!
389 * @param psz1 target
390 * @param psz2 source
391 * @param cch length
392 */
393void kmemcpy(char *psz1, const char *psz2, int cch)
394{
395 while (cch-- != 0)
396 *psz1++ = *psz2++;
397}
398
399
400/**
401 * Finds psz2 in psz2.
402 * @returns Pointer to occurence of psz2 in psz1.
403 * @param psz1 String to be search.
404 * @param psz2 Substring to search for.
405 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
406 */
407char *kstrstr(const char *psz1, const char *psz2)
408{
409 while (*psz1 != '\0')
410 {
411 register int i = 0;
412 while (psz2[i] != '\0' && psz1[i] == psz2[i])
413 i++;
414
415 /* found it? */
416 if (psz2[i] == '\0')
417 return (char*)psz1;
418 if (psz1[i] == '\0' )
419 break;
420 psz1++;
421 }
422
423 return NULL;
424}
425
426
427#if 0 /* not in use */
428/**
429 * kstrcmp - String compare
430 * @returns 0 - equal else !0
431 * @param psz1 String 1
432 * @param psz2 String 2
433 */
434int kstrcmp(const char *psz1, const char *psz2);
435{
436 while (*psz1 == *psz2 && *psz1 != '\0' && *psz2 != '\0')
437 {
438 psz1++;
439 psz2++;
440 }
441 return *psz1 - *psz2;
442}
443#endif
444
445
446/**
447 * kstrncmp - String 'n' compare.
448 * @returns 0 - equal else !0
449 * @param p1 String 1
450 * @param p2 String 2
451 * @param len length
452 */
453int kstrncmp(register const char *psz1, register const char *psz2, int cch)
454{
455 int i = 0;
456 while (i < cch && *psz1 == *psz2 && *psz1 != '\0' && *psz2 != '\0')
457 {
458 psz1++;
459 psz2++;
460 i++;
461 }
462
463 return i - cch;
464}
465
466
467#if 0 /* not in use */
468/**
469 * kstrnicmp - String 'n' compare, case-insensitive.
470 * @returns 0 - equal else !0
471 * @param p1 String 1
472 * @param p2 String 2
473 * @param len length
474 */
475int kstrnicmp(const char *psz1, const char *psz2, int cch)
476{
477 register char ch1, ch2;
478
479 do
480 {
481 ch1 = *psz1++;
482 if (ch1 >= 'A' && ch1 <= 'Z')
483 ch1 += 'a' - 'A'; /* to lower case */
484 ch2 = *psz2++;
485 if (ch2 >= 'A' && ch2 <= 'Z')
486 ch2 += 'a' - 'A'; /* to lower case */
487 } while (--cch > 0 && ch1 == ch2 && ch1 != '\0' && ch2 != '\0');
488
489 return ch1 - ch2;
490}
491#endif
492
493
494/**
495 * kstrlen - String length.
496 * @returns Length of the string.
497 * @param psz Pointer to string.
498 * @status completely implemented and tested.
499 * @author knut st. osmundsen
500 */
501int kstrlen(register const char * psz)
502{
503 register int cch = 0;
504 while (*psz++ != '\0')
505 cch++;
506 return cch;
507}
508
509
510/**
511 * String copy (strcpy).
512 * @returns Pointer to target string.
513 * @param pszTarget Target string.
514 * @param pszSource Source string.
515 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
516 */
517char * kstrcpy(char * pszTarget, register const char * pszSource)
518{
519 register char *psz = pszTarget;
520
521 while (*pszSource != '\0')
522 *psz++ = *pszSource++;
523 *psz = '\0';
524 return pszTarget;
525}
526
527
528
529
530/**
531 * Copy an argument to a buffer. Ie. "-K[=|:]c:\os2krnl ....". Supports quotes
532 * @returns Number of chars of pszArg that has been processed.
533 * @param pszTarget - pointer to target buffer.
534 * @param pszArg - pointer to source argument string.
535 * @param cchMaxlen - maximum chars to copy.
536 */
537int kargncpy(char * pszTarget, const char * pszArg, unsigned cchMaxlen)
538{
539 int i = 0;
540 int fQuote = FALSE;
541
542 /* skip option word/letter */
543 while (*pszArg != '\0' && *pszArg != ' ' && *pszArg != ':' &&
544 *pszArg != '=' && *pszArg != '-' && *pszArg != '/')
545 {
546 pszArg++;
547 i++;
548 }
549
550 if (*pszArg == ' ' || *pszArg == '-' || *pszArg == '/' || *pszArg == '\0')
551 return 0;
552
553
554 do
555 {
556 pszArg++;
557 i++;
558 } while (*pszArg != '\0' && *pszArg == ' ');
559
560 /* copy maxlen or less */
561 /* check for quotes */
562 if (*pszArg == '"')
563 {
564 fQuote = TRUE;
565 pszArg++;
566 i++;
567 }
568 /* copy loop */
569 while (cchMaxlen > 1 && (fQuote ? *pszArg != '"' : *pszArg != ' ') && *pszArg != '\0')
570 {
571 *pszTarget++ = *pszArg++;
572 i++;
573 cchMaxlen--;
574 }
575
576 /* terminate pszTarget */
577 pszTarget = '\0';
578
579 return i;
580}
581
582
583/**
584 * Get the message text for an error message.
585 * @returns Pointer to error text. NULL if not found.
586 * @param sErr Error code id.
587 * @status completely implemented.
588 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
589 */
590const char * GetErrorMsg(short sErr)
591{
592 int i;
593 for (i = 0; i < sizeof(aErrorMsgs) / sizeof(aErrorMsgs[0]); i++)
594 {
595 if (aErrorMsgs[i].sErr == sErr)
596 return aErrorMsgs[i].pszMsg;
597 }
598 return NULL;
599}
600
601
602
603/*******************************************************************************
604* Implementation Of The Important Functions *
605*******************************************************************************/
606/**
607 * Checks if this kernel is within the kernel symbol database.
608 * If an entry for the kernel is found, the data is copied from the
609 * database entry to aImportTab.
610 * @returns NO_ERROR on succes (0)
611 * 1 if not found.
612 * Error code on error.
613 * @param usBuild Build level.
614 * @param fKernel Kernel (type) flags. (KF_* from options.h)
615 * @param cObjects Count of object in the running kernel.
616 * @sketch Loop thru the table.
617 * @status completely implemented.
618 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
619 */
620int LookupKrnlEntry(unsigned short usBuild, unsigned short fKernel, unsigned char cObjects)
621{
622 int i;
623
624 /*
625 * Loop tru the DB entries until a NULL pointer is found.
626 */
627 for (i = 0; aKrnlSymDB[i].usBuild != 0; i++)
628 {
629 if ( aKrnlSymDB[i].usBuild == usBuild
630 && aKrnlSymDB[i].fKernel == fKernel
631 && aKrnlSymDB[i].cObjects == cObjects)
632 { /* found matching entry! */
633 int j;
634 int rc;
635 register PKRNLDBENTRY pEntry = &aKrnlSymDB[i];
636
637 dprintf(("LookUpKrnlEntry - found entry for this kernel!\n"));
638 kstrcpy(szSymbolFile, "Win32k Symbol Database");
639
640 /*
641 * Copy symbol data from the DB to aImportTab.
642 */
643 for (j = 0; j < NBR_OF_KRNLIMPORTS; j++)
644 {
645 aImportTab[j].offObject = pEntry->aSyms[j].offObject;
646 aImportTab[j].iObject = pEntry->aSyms[j].iObject;
647 aImportTab[j].ulAddress = paKrnlOTEs[pEntry->aSyms[j].iObject].ote_base
648 + pEntry->aSyms[j].offObject;
649 aImportTab[j].usSel = paKrnlOTEs[pEntry->aSyms[j].iObject].ote_sel;
650 aImportTab[j].fFound = (char)((aImportTab[j].offObject != 0xFFFFFFFFUL) ? 1 : 0);
651 dprintf((" %-3d addr=0x%08lx off=0x%08lx %s\n",
652 j, aImportTab[j].ulAddress, aImportTab[j].offObject,
653 aImportTab[j].achName));
654 }
655
656 /* Verify prologs*/
657 rc = VerifyPrologs();
658
659 /* set sym name on success or complain on error */
660 if (rc != 0)
661 {
662 printf16("Warning: The Win32k Symbol Database entry found.\n"
663 " But, VerifyPrologs() returned rc=0x%x and iProc=%d\n", rc, iProc);
664 DosSleep(3000);
665 }
666
667 return rc;
668 }
669 }
670
671 /* not found */
672 return ERROR_PROB_SYMDB_KRNL_NOT_FOUND;
673}
674
675
676/**
677 * Verifies the that the addresses in aImportTab are valid.
678 * This is done at Ring-0 of course.
679 * @returns NO_ERROR (ie. 0) on success. iProc = -1
680 * The appropriate OS/2 or Win32k return code on success. iProc
681 * is set to the failing procedure (if appliable).
682 */
683int VerifyPrologs(void)
684{
685#if !defined(EXTRACT)
686 APIRET rc;
687 HFILE hDev0 = 0;
688 USHORT usAction = 0;
689
690 /* Set the failing procedure number to -1. */
691 iProc = -1;
692
693 /* Open the elf device driver. */
694 rc = DosOpen("\\dev\\elf$", &hDev0, &usAction, 0UL, FILE_NORMAL,
695 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
696 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
697 0UL);
698 if (rc == NO_ERROR)
699 {
700 D16VERIFYIMPORTTABDATA Data = {0};
701
702 /* Issue the VerifyImportTab IOCtl call. */
703 rc = DosDevIOCtl(&Data, "", D16_IOCTL_VERIFYIMPORTTAB, D16_IOCTL_CAT, hDev0);
704 DosClose(hDev0);
705 if (rc == NO_ERROR)
706 {
707 if (Data.usRc != NO_ERROR)
708 {
709 /* set the appropriate return values. */
710 rc = (Data.usRc & ERROR_D32_ERROR_MASK) + ERROR_PROB_SYM_D32_FIRST;
711 if (Data.usRc & ERROR_D32_PROC_FLAG)
712 iProc = (Data.usRc & ERROR_D32_PROC_MASK) >> ERROR_D32_PROC_SHIFT;
713 }/* else success */
714 }
715 else
716 {
717 dprintf(("DosDevIOCtl failed with rc=%d\n", rc));
718 DosSleep(3000);
719 }
720 }
721 else
722 {
723 dprintf(("DosOpen Failed with rc=%d\n", rc));
724 DosSleep(3000);
725 }
726
727 return rc;
728#else
729 return 0;
730#endif
731}
732
733
734/**
735 * Check a symbol file. Searches for the wanted entry-point addresses.
736 * @returns 0 on success - something else on failiure.
737 * @param pszFilename Name of file to probe.
738 * @precond Must be called after kernel-file is found and processed.
739 * @remark Error codes starts at -50.
740 */
741int ProbeSymFile(const char * pszFilename)
742{
743 HFILE hSym; /* Filehandle */
744 int cLeftToFind; /* Symbols left to find */
745 unsigned long iSeg; /* Outer search loop: Segment number */
746 unsigned iSym; /* Middle search loop: Symbol number */
747 unsigned i; /* Inner search loop: ProcTab index */
748 int rc;
749
750 MAPDEF MapDef; /* Mapfile header */
751 SEGDEF SegDef; /* Segment header */
752 SYMDEF32 SymDef32; /* Symbol definition 32-bit */
753 SYMDEF16 SymDef16; /* Symbol definition 16-bit */
754 char achBuffer[256]; /* Name buffer */
755 unsigned long offSegment; /* Segment definition offset */
756 unsigned long offSymPtr; /* Symbol pointer(offset) offset */
757 unsigned short offSym; /* Symbol definition offset */
758
759
760 /*
761 * Open the symbol file
762 */
763 hSym = fopen(pszFilename, "rb");
764 if (hSym==0)
765 {
766 dprintf(("Error opening file %s\n", pszFilename));
767 return ERROR_PROB_SYM_FILE_NOT_FOUND;
768 }
769 dprintf(("\nSuccessfully opened symbolfile: %s\n", pszFilename));
770
771
772 /*
773 * (Open were successfully.)
774 * Now read header and display it.
775 */
776 rc = fread(&MapDef, sizeof(MAPDEF), 1, hSym);
777 if (!rc)
778 { /* oops! read failed, close file and fail. */
779 fclose(hSym);
780 return ERROR_PROB_SYM_READERROR;
781 }
782 achBuffer[0] = MapDef.achModName[0];
783 fread(&achBuffer[1], 1, MapDef.cbModName, hSym);
784 achBuffer[MapDef.cbModName] = '\0';
785 dprintf(("*Module name: %s\n", achBuffer));
786 dprintf(("*Segments: %d\n*MaxSymbolLength: %d\n", MapDef.cSegs, MapDef.cbMaxSym));
787 dprintf(("*ppNextMap: 0x%x\n", MapDef.ppNextMap ));
788
789
790 /*
791 * Verify that the modulename of the symbol file is OS2KRNL.
792 */
793 if (MapDef.cbModName == 7 && kstrncmp(achBuffer, "OS2KRNL", 7) != 0)
794 { /* modulename was not OS2KRNL, fail. */
795 dprintf(("Modulename verify failed\n"));
796 fclose(hSym);
797 return ERROR_PROB_SYM_INVALID_MOD_NAME;
798 }
799
800
801 /*
802 * Verify that the number of segments is equal to the number objects in OS2KRNL.
803 */
804 #ifndef EXTRACT
805 if (MapDef.cSegs != cObjects)
806 { /* incorrect count of segments. */
807 dprintf(("Segment No. verify failed\n"));
808 fclose(hSym);
809 return ERROR_PROB_SYM_SEGS_NE_OBJS;
810 }
811 #endif /* !EXTRACT */
812
813
814 /*
815 * Reset ProcTab
816 */
817 for (i = 0; i < NBR_OF_KRNLIMPORTS; i++)
818 {
819 aImportTab[i].fFound = 0;
820 #ifdef DEBUG
821 aImportTab[i].offObject = 0;
822 aImportTab[i].ulAddress = 0;
823 aImportTab[i].usSel = 0;
824 #endif
825 }
826
827
828 /*
829 * Fileoffset of the first segment.
830 * And set cLeftToFind.
831 */
832 offSegment = SEGDEFOFFSET(MapDef);
833 cLeftToFind = NBR_OF_KRNLIMPORTS;
834
835 /*
836 * Search thru the entire file, segment by segment.
837 *
838 * ASSUME: last segment is the only 32-bit code segment.
839 *
840 */
841 for (iSeg = 0; iSeg < MapDef.cSegs; iSeg++, offSegment = NEXTSEGDEFOFFSET(SegDef))
842 {
843 int fSegEPTBitType; /* Type of segment, 16 or 32 bit, expressed in EPT_XXBIT flags */
844 int fCode; /* Set if this is a code segment, else clear. */
845
846 /*
847 * Read the segment definition.
848 */
849 if (fseek(hSym, offSegment, SEEK_SET))
850 { /* Failed to seek to the segment definition, fail! */
851 fclose(hSym);
852 return ERROR_PROB_SYM_SEG_DEF_SEEK;
853 }
854 rc = fread(&SegDef, sizeof(SEGDEF), 1, hSym);
855 if (!rc)
856 { /* Failed to read the segment definition, fail! */
857 fclose(hSym);
858 return ERROR_PROB_SYM_SEG_DEF_READ;
859 }
860
861 /*
862 * Some debugging info.
863 */
864 achBuffer[0] = SegDef.achSegName[0];
865 fread(&achBuffer[1], 1, SegDef.cbSegName, hSym);
866 achBuffer[SegDef.cbSegName] = '\0';
867 dprintf(("Segment %.2li Flags=0x%02x cSymbols=0x%04x Name=%s\n",
868 iSeg, SegDef.bFlags, SegDef.cSymbols, &achBuffer[0]));
869
870 /*
871 * Determin segment bit type.
872 */
873 fSegEPTBitType = SEG32BitSegment(SegDef) ? EPT_32BIT : EPT_16BIT;
874 fCode = kstrstr(achBuffer, "CODE") != NULL;
875
876 /*
877 * Search thru all the symbols in this segment
878 * while we look for the requested symbols in aImportTab.
879 */
880 for (iSym = 0; iSym < SegDef.cSymbols && cLeftToFind; iSym++)
881 {
882 IMPORTKRNLSYM * pImport;
883 unsigned cchName;
884
885 /*
886 * Fileoffset of the current symbol.
887 * Set filepointer to that position.
888 * Read word (which is the offset of the symbol).
889 */
890 offSymPtr = SYMDEFOFFSET(offSegment, SegDef, iSym);
891 rc = fseek(hSym, offSymPtr, SEEK_SET);
892 if (rc)
893 { /* Symboloffset seek failed, try read next symbol. */
894 dprintf(("Warning: Seek failed (offSymPtr=%d, rc=%d)\n", offSymPtr, rc));
895 continue;
896 }
897 rc = fread(&offSym, sizeof(unsigned short int), 1, hSym);
898 if (!rc)
899 { /* Symboloffset read failed, try read next symbol. */
900 dprintf(("Warning: read failed (offSymPtr=%d, rc=%d)\n", offSymPtr, rc));
901 continue;
902 }
903 rc = fseek(hSym, offSym + offSegment, SEEK_SET);
904 if (rc)
905 { /* Symbol Seek failed, try read next symbol. */
906 dprintf(("Warning: Seek failed (offSym=%d, rc=%d)\n", offSym, rc));
907 continue;
908 }
909
910
911 /*
912 * Read symbol and symbolname.
913 */
914 if (SegDef.bFlags & 0x01)
915 rc = fread(&SymDef32, sizeof(SYMDEF32), 1, hSym);
916 else
917 rc = fread(&SymDef16, sizeof(SYMDEF16), 1, hSym);
918 if (!rc)
919 { /* Symbol read failed, try read next symbol */
920 dprintf(("Warning: Read(1) failed (offSym=%d, rc=%d)\n", offSym, rc));
921 continue;
922 }
923 achBuffer[0] = (SegDef.bFlags & 0x01) ? SymDef32.achSymName[0] : SymDef16.achSymName[0];
924 cchName = (SegDef.bFlags & 0x01) ? SymDef32.cbSymName : SymDef16.cbSymName;
925 rc = fread(&achBuffer[1], 1, cchName, hSym);
926 if (!rc)
927 { /* Symbol read failed, try read next symbol */
928 dprintf(("Warning: Read(2) failed (offSym=%d, rc=%d)\n", offSym, rc));
929 continue;
930 }
931 achBuffer[cchName] = '\0';
932
933
934 /*
935 * Search proctable.
936 */
937 for (i = 0, pImport = &aImportTab[0]; i < NBR_OF_KRNLIMPORTS; i++, pImport++)
938 {
939 if (!pImport->fFound /* Not allready found */
940 && (pImport->fType & EPT_VARIMPORT ? !fCode : fCode) /* Don't look for code in a data segment */
941 && pImport->cchName == cchName /* Equal name length */
942 && kstrncmp(pImport->achName, achBuffer, cchName) == 0 /* Equal name */
943 )
944 { /* Symbol was found */
945 pImport->offObject = (SegDef.bFlags & 0x01 ? SymDef32.wSymVal : SymDef16.wSymVal);
946 pImport->ulAddress = pImport->offObject + paKrnlOTEs[iSeg].ote_base;
947 pImport->iObject = (unsigned char)iSeg;
948 pImport->usSel = paKrnlOTEs[iSeg].ote_sel;
949 dprintf(("debug: base=%lx, size=%lx iSeg=%d\n", paKrnlOTEs[iSeg].ote_base, paKrnlOTEs[iSeg].ote_size, iSeg));
950
951 /* Paranoia test! */
952 #ifndef EXTRACT
953 if (pImport->offObject < paKrnlOTEs[iSeg].ote_size)
954 {
955 pImport->fFound = TRUE;
956 cLeftToFind--;
957 dprintf(("Found: %s at off 0x%lx addr 0x%lx, sel=0x%x\n",
958 pImport->achName, pImport->offObject,
959 pImport->ulAddress, pImport->usSel));
960 }
961 else/* test failed, continue on next symbol*/
962 dprintf(("Error: Paranoia test failed for %s\n", pImport->achName));;
963 #else
964 pImport->fFound = TRUE;
965 cLeftToFind--;
966 #endif /* !EXTRACT */
967 break;
968 }
969
970 } /* aImportTab for-loop */
971
972 } /* Symbol for-loop */
973
974 } /* Segment for-loop */
975
976 /*
977 * Close symbol file.
978 */
979 fclose(hSym);
980
981 /*
982 * If not all procedures were found fail.
983 */
984 for (i = 0; i < NBR_OF_KRNLIMPORTS; i++)
985 if (!aImportTab[i].fFound && !EPTNotReq(aImportTab[i]))
986 return ERROR_PROB_SYM_IMPORTS_NOTFOUND;
987
988 /*
989 * Verify function prologs and return.
990 */
991 return VerifyPrologs();
992}
993
994
995/**
996 * Get kernelinformation (OTEs (object table entries), build, type, debug...)
997 * @returns 0 on success.
998 * options.ulBuild, fchType, fDebug, cObjects and paKrnlOTEs is set on successful return.
999 * Not 0 on error.
1000 */
1001int GetKernelInfo(void)
1002{
1003#if !defined(EXTRACT) /* This IOCtl is not available after inittime! */
1004 static KRNLINFO DATA16_INIT KrnlInfo = {0};
1005 APIRET rc;
1006 HFILE hDev0 = 0;
1007 USHORT usAction = 0;
1008
1009 /*
1010 * Issue an IOCtl to elf$ to query kernel information.
1011 */
1012 rc = DosOpen("\\dev\\elf$", &hDev0, &usAction, 0UL, FILE_NORMAL,
1013 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
1014 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
1015 0UL);
1016 if (rc == NO_ERROR)
1017 {
1018 rc = DosDevIOCtl(&KrnlInfo, "", D16_IOCTL_GETKRNLINFO, D16_IOCTL_CAT, hDev0);
1019 if (rc == NO_ERROR)
1020 {
1021 #ifdef DEBUG
1022 unsigned i;
1023 #endif
1024
1025 /*
1026 * Set the exported parameters
1027 */
1028 options.ulBuild = KrnlInfo.ulBuild;
1029 options.fKernel = KrnlInfo.fKernel;
1030 cObjects = KrnlInfo.cObjects;
1031 paKrnlOTEs = &KrnlInfo.aObjects[0];
1032
1033 /*
1034 * If debugging probkrnl dump kernel OTEs.
1035 */
1036 #ifdef DEBUG
1037 dprintf(("debug: kernel OTE:\n"));
1038 for (i = 0; i < cObjects; i++)
1039 dprintf(("debug: no.%2d base=%lx size=%lx sel=%x\n",
1040 i,
1041 paKrnlOTEs[i].ote_base,
1042 paKrnlOTEs[i].ote_size,
1043 paKrnlOTEs[i].ote_sel));
1044 #endif
1045 }
1046 DosClose(hDev0);
1047 }
1048
1049 if (rc != NO_ERROR)
1050 printf16("Failed to get kernel OTEs. rc=%d\n", rc);
1051
1052 return rc;
1053
1054#else
1055 return 0;
1056#endif
1057}
1058
1059
1060/**
1061 * Shows result of kernelprobing if not quiet or on error.
1062 * @param rc Return code.
1063 */
1064void ShowResult(int rc)
1065{
1066 int i;
1067
1068 /*
1069 * Complain even if quiet on error
1070 */
1071 if (!options.fQuiet || rc != NO_ERROR)
1072 {
1073 printf16("Win32k - Odin32 support driver. (Built %s %s)\n",
1074 (NPSZ)szBuildTime, (NPSZ)szBuildDate);
1075
1076 /*
1077 * kernel stuff
1078 */
1079 if (rc == NO_ERROR || rc > ERROR_PROB_KRNL_LAST)
1080 printf16(" Build: %ld - v%d.%d\n",
1081 options.ulBuild, options.usVerMajor, options.usVerMinor);
1082 else if (rc >= ERROR_PROB_KRNL_FIRST)
1083 printf16(" Kernel probing failed with rc=%d.\n", rc);
1084 else
1085 printf16(" Failed before probing kernel.\n");
1086
1087 /*
1088 * symbol-file
1089 */
1090 if (rc == NO_ERROR || (rc > ERROR_PROB_SYM_LAST && szSymbolFile[0] != '\0'))
1091 printf16(" Found symbolfile: %s\n", (NPSZ)szSymbolFile);
1092 else if (rc >= ERROR_PROB_SYM_FIRST)
1093 printf16(" Failed to find symbolfile!\n");
1094 else
1095 printf16(" Failed before searching for symbolfile.\n");
1096
1097 /*
1098 * function listing
1099 */
1100 if (options.fLogging)/* || rc != NO_ERROR)*/
1101 {
1102 for (i = 0; i < NBR_OF_KRNLIMPORTS; i++)
1103 {
1104 printf16(" %-21s at ", aImportTab[i].achName);
1105 if (aImportTab[i].fFound)
1106 printf16("0x%08lx%s", aImportTab[i].ulAddress, (i % 2) == 0 ? "" : "\n");
1107 else
1108 printf16("not found!%s", (i % 2) == 0 ? "" : "\n");
1109 }
1110 if (i % 2) printf16("\n");
1111 }
1112
1113 /*
1114 * Display error code.
1115 */
1116 if (rc != NO_ERROR)
1117 {
1118 const char *psz = GetErrorMsg(rc);
1119 printf16("ProbeKernel failed with rc=%d. iProc=%x\n", rc, iProc);
1120 if (psz) printf16("%s\n", psz);
1121 }
1122 }
1123}
1124
1125
1126/**
1127 * "main" function.
1128 * Note that the option -Noloader causes nothing to be done.
1129 * @returns 0 on success, something else on error.
1130 * @param pReqPack Pointer to init request packet
1131 * @remark
1132 */
1133int ProbeKernel(PRPINITIN pReqPack)
1134{
1135 int rc;
1136 int i;
1137 int n;
1138 SEL selGIS;
1139 SEL selLIS;
1140 PGINFOSEG pGIS;
1141 PLINFOSEG pLIS;
1142 USHORT usBootDrive;
1143
1144 /*----------------*/
1145 /* parse InitArgs */
1146 /*----------------*/
1147 if (pReqPack != NULL && pReqPack->InitArgs != NULL)
1148 {
1149 n = kstrlen(pReqPack->InitArgs);
1150 for (i = 0; i < n; i++)
1151 {
1152 if ((pReqPack->InitArgs[i] == '/' || pReqPack->InitArgs[i] == '-') && (i+1) < n)
1153 {
1154 i++;
1155 switch (pReqPack->InitArgs[i])
1156 {
1157 case 'n':
1158 case 'N': /* NoLoader */
1159 options.fNoLoader = TRUE;
1160 return 0;
1161
1162 case 'q':
1163 case 'Q': /* Quiet */
1164 options.fQuiet = TRUE;
1165 break;
1166
1167 case 's':
1168 case 'S': /* Symbol file */
1169 i++;
1170 if ( pReqPack->InitArgs[i] != 'c' && pReqPack->InitArgs[i] != 'C'
1171 && pReqPack->InitArgs[i] != 'm' && pReqPack->InitArgs[i] != 'M'
1172 ) /* -script and -smp is ignored */
1173 i += kargncpy(szSymbolFile, &pReqPack->InitArgs[i], sizeof(szSymbolFile));
1174 break;
1175
1176 case 'v':
1177 case 'V': /* Verbose */
1178 options.fQuiet = FALSE;
1179 break;
1180 }
1181 }
1182 }
1183 }
1184
1185 /*---------------------*/
1186 /* determin boot drive */
1187 /*---------------------*/
1188 rc = DosGetInfoSeg(&selGIS, &selLIS);
1189 if (rc != NO_ERROR)
1190 return rc;
1191
1192 pLIS = MAKEPLINFOSEG(selLIS);
1193 pGIS = MAKEPGINFOSEG(selGIS);
1194 usBootDrive = pGIS->bootdrive;
1195#ifndef R3TST
1196 options.usVerMajor = pGIS->uchMajorVersion;
1197 options.usVerMinor = pGIS->uchMinorVersion;
1198#else
1199 if (usFakeVerMajor == 0)
1200 {
1201 usFakeVerMajor = pGIS->uchMajorVersion;
1202 usFakeVerMinor = pGIS->uchMinorVersion;
1203 }
1204 options.usVerMajor = usFakeVerMajor;
1205 options.usVerMinor = usFakeVerMinor;
1206#endif
1207 dprintf(("BootDrive: %d\n", usBootDrive));
1208
1209 /* set driveletter in constants strings */
1210 usBootDrive = (char)usBootDrive + (char)'a' - 1;
1211 for (i = 0; apszSym[i] != NULL; i++)
1212 apszSym[i][0] = (char)usBootDrive;
1213
1214 /*-----------------*/
1215 /* get kernel info */
1216 /*-----------------*/
1217 rc = GetKernelInfo();
1218
1219 /*--------------*/
1220 /* read symfile */
1221 /*--------------*/
1222 if (!rc)
1223 {
1224 rc = 1;
1225 if (szSymbolFile[0] != '\0')
1226 {
1227 rc = ProbeSymFile(szSymbolFile);
1228 if (rc)
1229 {
1230 printf16("Warning: Invalid symbol file specified. rc=%x iProc=%d\n"
1231 " Tries defaults.\n", rc, iProc);
1232 szSymbolFile[0] = '\0';
1233 DosSleep(3000);
1234 }
1235 }
1236 if (rc != NO_ERROR) /* if user sym failed or don't exists. */
1237 {
1238 /*
1239 * Check database - only if not a debug kernel!
1240 * You usually have a .sym-file when using a debug kernel.
1241 * (This is because I am unable to distinguish between half and
1242 * all strict kernels...)
1243 */
1244 if ((options.fKernel & KF_DEBUG) ||
1245 (rc = LookupKrnlEntry((unsigned short)options.ulBuild,
1246 (unsigned short)options.fKernel,
1247 cObjects)
1248 ) != NO_ERROR
1249 )
1250 {
1251 #if 1 /* ndef R3TST */
1252 APIRET rc2;
1253 /* search on disk */
1254 i = 0;
1255 while (apszSym[i] != NULL
1256 && (rc2 = ProbeSymFile(apszSym[i])) != NO_ERROR
1257 )
1258 {
1259 i++;
1260 if (rc2 >= ERROR_PROB_SYM_D32_FIRST)
1261 rc = rc2;
1262 }
1263 if (rc2 == NO_ERROR)
1264 {
1265 kstrcpy(szSymbolFile, apszSym[i]);
1266 rc = NO_ERROR;
1267 }
1268 #endif
1269 }
1270 }
1271 }
1272
1273 /* Show the result and set return-value */
1274 dprintf(("rc=%d(0x%x); i=%d; iProc=%d\n", rc, rc, i, iProc));
1275 ShowResult(rc);
1276
1277 return rc;
1278}
1279
Note: See TracBrowser for help on using the repository browser.