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

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

Display build time and date.

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