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

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

Implemented tool for generating calltab for kernel imports. (mkcalltab)
Implemented API for accessing memory in another process. (*ProcessReadWrite)
Added kernel imports needed to implemented ProcessReadWrite.
Removed unused kernel imports.

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