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

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

Prepared for event overloading.

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