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

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

Calltable fixes. Handle event. New 14062e kernels.

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