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

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

Added a few new imports and overrides.

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