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

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

Removed a "register" statement to solve a compiler problem.

File size: 43.4 KB
Line 
1/* $Id: probkrnl.c,v 1.29 2000-12-02 23:28:51 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 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.