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

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

Added new imports (quite a lot).

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