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

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

Moved ldrCalls.h into the OS2Krnl.h tree as OS2KLDR.h.
Also moved the Ldr definitions from OS2Krnl.h and into OS2KLDR.h.

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