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

Last change on this file since 6279 was 6279, checked in by bird, 24 years ago

New imports.

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