source: trunk/src/win32k/dev32/d32init.c@ 1467

Last change on this file since 1467 was 1467, checked in by bird, 26 years ago

Corrections to make win32k work.
(And now it does work, at least at my test machine...)

File size: 11.4 KB
Line 
1/* $Id: d32init.c,v 1.2 1999-10-27 02:02:54 bird Exp $
2 *
3 * d32init.c - 32-bits init routines.
4 *
5 * Copyright (c) 1998-1999 knut st. osmundsen
6 *
7 */
8
9/*******************************************************************************
10* Defined Constants *
11*******************************************************************************/
12#define MAXSIZE_PROLOG 0x10 /* Note that this must be synced with */
13 /* the one used in calltab.asm. */
14#define static
15
16#define INCL_DOSERRORS
17#define INCL_NOPMAPI
18#define LDR_INCL_INITONLY
19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#include <os2.h>
24
25#include <string.h>
26
27#include "OS2Krnl.h"
28#include "options.h"
29#include "dev1632.h"
30#include "dev32.h"
31#include "probkrnl.h"
32#include "log.h"
33#include "asmutils.h"
34#include "malloc.h"
35#include "ldr.h"
36#include "ldrCalls.h"
37
38
39/*******************************************************************************
40* Internal Functions *
41*******************************************************************************/
42static int interpretFunctionProlog(char *p);
43static int procInit(void);
44
45
46/* externs located in 16-bit data segement */
47extern ULONG _TKSSBase16;
48extern USHORT _R0FlatCS16;
49extern USHORT _R0FlatDS16;
50
51
52/* extern(s) located in calltab.asm */
53extern char callTab[NUMBER_OF_PROCS][MAXSIZE_PROLOG];
54
55
56/**
57 * Ring-0, 32-bit, init function.
58 * @returns Status word.
59 * @param pRpInit Pointer init request packet.
60 * @sketch Set TKSSBase32.
61 * Set default parameters.
62 * Parse command line options.
63 * Show (kprint) configuration.
64 * Init heap.
65 * Init ldr.
66 * Init procs. (overloaded ldr procedures)
67 * @status completely implemented.
68 * @author knut st. osmundsen
69 */
70USHORT _loadds _Far32 _Pascal R0Init32(RP32INIT *pRpInit)
71{
72 char *pszTmp2;
73 char *pszTmp;
74
75 pulTKSSBase32 = (PULONG)_TKSSBase16;
76
77 SET_OPTIONS_TO_DEFAULT(options);
78
79 /*---------------------*/
80 /* commandline options */
81 /*---------------------*/
82 kprintf(("Options start\n"));
83 pszTmp = strpbrk(pRpInit->InitArgs, "-/");
84 while (pszTmp != NULL)
85 {
86 char cch;
87 pszTmp++; //skip [-/]
88 cch = strlen(pszTmp);
89 switch (*pszTmp)
90 {
91 case 'C': /* -C[1|2] - com-port no, def:-C2 */
92 switch (pszTmp[1])
93 {
94 case '1':
95 options.usCom = OUTPUT_COM1;
96 break;
97
98 case '2':
99 default:
100 options.usCom = OUTPUT_COM2;
101 }
102 break;
103
104 case 'L': /* -L[..]<:|=| >[<Y..|E..| > | <N..|D..>] */
105 pszTmp2 = strpbrk(pszTmp, ":=/- ");
106 if (pszTmp2 != NULL && (int)(pszTmp2-pszTmp) < cch-1
107 && (pszTmp2[1] == 'N' ||pszTmp2[1] == 'n' || pszTmp2[1] == 'D' || pszTmp2[1] == 'd')
108 )
109 options.fLogging = FALSE;
110 else
111 options.fLogging = TRUE;
112 break;
113
114
115 case 'Q': /* quiet initialization */
116 options.fQuiet = TRUE;
117 break;
118
119 case 'S': /* SMP kernel */
120 options.fKernel = KF_SMP;
121 break;
122
123 case 'V': /* verbose initialization */
124 options.fQuiet = FALSE;
125 break;
126
127 case 'U': /* UNI kernel */
128 options.fKernel = KF_SMP;
129 break;
130 }
131 pszTmp = strpbrk(pszTmp, "-/");
132 }
133
134 /* Transfer version and build number from 16-bit probkrnl.c */
135 options.ulBuild = _ulBuild;
136 options.usVerMajor = _usVerMajor;
137 options.usVerMinor = _usVerMinor;
138
139 /* log option summary */
140 kprintf(("Options - Summary\n"));
141 kprintf(("\tKernel: ver%d.%d build %d type %s\n",
142 options.usVerMajor,
143 options.usVerMinor,
144 options.ulBuild,
145 (options.fKernel & KF_SMP) ? "SMP" : "UNI"
146 ));
147 kprintf(("\tCom port no.%d\n", options.usCom));
148 if (options.fQuiet)
149 kprintf(("\tQuiet init\n"));
150 else
151 kprintf(("\tVerbose init\n"));
152 if (options.fLogging)
153 kprintf(("\tlogging enabled\n"));
154 else
155 kprintf(("\tlogging disabled\n"));
156 /* end option summary */
157
158
159 /*
160 * init sub-parts
161 */
162 /* heap */
163 if (heapInit(HEAP_SIZE) != NO_ERROR)
164 return STATUS_DONE | STERR | ERROR_I24_QUIET_INIT_FAIL;
165
166 /* loader */
167 if (ldrInit() != NO_ERROR)
168 return STATUS_DONE | STERR | ERROR_I24_QUIET_INIT_FAIL;
169
170 /* functionoverrides */
171 if (procInit() != NO_ERROR)
172 return STATUS_DONE | STERR | ERROR_I24_QUIET_INIT_FAIL;
173
174 return STATUS_DONE;
175}
176
177
178/**
179 * Verifies the aProcTab.
180 * @returns 0 if ok. !0 if not ok.
181 * @remark Called from IOCtl.
182 */
183USHORT _loadds _Far32 _Pascal VerifyProcTab32(void)
184{
185 int i;
186 int cb;
187
188 /* verify */
189 for (i = 0; i < NUMBER_OF_PROCS; i++)
190 {
191 /* verify that it is found */
192 if (!_aProcTab[i].fFound)
193 {
194 kprintf(("VerifyProcTab32: procedure no.%d was not found!\n", i));
195 return STATUS_DONE | STERR | 1;
196 }
197
198 /* verify read/writeable. - FIXME */
199 if (_aProcTab[i].ulAddress < 0xffe00000UL)
200 {
201 kprintf(("VerifyProcTab32: procedure no.%d has an invlalid address, %#08x!\n",
202 i, _aProcTab[i].ulAddress));
203 return STATUS_DONE | STERR | 2;
204 }
205
206 /* verify known function prolog. (only EPT_PROC) */
207 if (_aProcTab[i].fType == EPT_PROC)
208 {
209 if ((cb = interpretFunctionProlog((char*)_aProcTab[i].ulAddress)) <= 0 && cb + 5 >= MAXSIZE_PROLOG)
210 {
211 kprintf(("VerifyProcTab32: verify failed for procedure no.%d\n",i));
212 return STATUS_DONE | STERR | 3;
213 }
214 }
215 else
216 {
217 kprintf(("VerifyProcTab32: only EPT_PROC is implemented\n",i));
218 return STATUS_DONE | STERR | 4;
219 }
220 }
221
222 return STATUS_DONE;
223}
224
225
226/**
227 * Get kernel OTEs
228 * @returns Strategy return code:
229 * STATUS_DONE on success.
230 * STATUS_DONE | STERR | errorcode on failure.
231 * @param pOTEBuf Pointer to output buffer.
232 * @status completely implemented and tested.
233 * @author knut st. osmundsen
234 * @remark Called from IOCtl.
235 */
236USHORT _loadds _Far32 _Pascal GetOTEs32(PKRNLOBJTABLE pOTEBuf)
237{
238 PMTE pMTE;
239 PSMTE pSMTE;
240 POTE pOTE;
241 int i;
242 USHORT usRc;
243
244 pMTE = GetOS2KrnlMTE();
245 if (pMTE != NULL)
246 {
247 pSMTE = pMTE->mte_swapmte;
248 if (pSMTE != NULL)
249 {
250 pOTEBuf->cObjects = pSMTE->smte_objcnt;
251 if (pSMTE->smte_objcnt <= MAXKRNLOBJECTS)
252 {
253 pOTE = pSMTE->smte_objtab;
254 if (pOTE != NULL)
255 {
256 for (i = 0; i < pOTEBuf->cObjects; i++)
257 memcpy((void*)&pOTEBuf->aObjects[i], &pOTE[i], sizeof(OTE));
258 usRc = 0;
259 }
260 else
261 usRc = 4;
262 }
263 else
264 usRc = 3;
265 }
266 else
267 usRc = 2;
268 }
269 else
270 usRc = 1;
271
272 if (usRc != 0)
273 kprintf(("GetOTEs32: failed. usRc = %d\n", usRc));
274
275 return usRc | (usRc != 0 ? STATUS_DONE | STERR : STATUS_DONE);
276}
277
278
279/**
280 * Interpret function prolog to find where to jmp back.
281 * @returns Length of prolog need to be copied - which is also the offset of
282 * where the jmp instr should be placed.
283 * On error it returns 0.
284 * @param p Pointer to prolog.
285 */
286static int interpretFunctionProlog(char *p)
287{
288 int length;
289 int rc;
290
291 /*
292 * check for the well known prolog (the only that is supported now)
293 * which is:
294 * push ebp
295 * mov ebp,esp
296 * or
297 * push ebp
298 * mov ecx, dword ptr [123407452]
299 */
300
301 if (p[0] == 0x55 && p[1] == 0x8b)
302 {
303 if (p[2] == 0xec)
304 rc = 3;
305 else
306 rc = 1;
307 while (rc < 5)
308 {
309 /*
310 * This is not at all very stable or correct - but it works
311 * for the current functions.
312 * There will never be any doubt when something goes wrong!
313 */
314 switch(p[rc])
315 {
316 case 0x33: /* xor (ldrClose, ldrOpen) */
317 rc +=2;
318 break;
319 case 0x8b:
320 if (p[rc+1] == 0x0d)
321 rc += 6;
322 else
323 rc += 2; /*????!*/
324 break;
325 case 0x8d: /* lea (ldrRead) */
326 rc += 3;
327 break;
328 case 0x83: /* sub (LDRQAppType) */
329 rc += 3;
330 break;
331 default:
332 kprintf(("interpretFunctionProlog: unknown instruction 0x%x \n", p[rc]));
333 return 0;
334 }
335 }
336 }
337 else
338 rc = 0;
339
340 return rc;
341}
342
343
344
345/**
346 * Initiates the overrided functions.
347 * @returns NO_ERROR on success. !0 on error.
348 */
349static int procInit(void)
350{
351 int i;
352 int cb;
353
354 /* verify */
355 for (i = 0; i < NUMBER_OF_PROCS; i++)
356 {
357 cb = interpretFunctionProlog((char*)_aProcTab[i].ulAddress);
358 if (cb <= 0 || cb + 5 >= MAXSIZE_PROLOG)
359 {
360 kprintf(("rehookFunctions: verify failed for procedure no.%d, cb=%d\n", i, cb));
361 return 1;
362 }
363 }
364
365 /* rehook */
366 for (i = 0; i < NUMBER_OF_PROCS; i++)
367 {
368 cb = interpretFunctionProlog((char*)_aProcTab[i].ulAddress);
369 if (cb > 0 && cb + 5 < MAXSIZE_PROLOG)
370 {
371 char *pMy;
372 switch (i)
373 {
374 case iLDRREAD: pMy = (char*)myldrRead; break;
375 case iLDROPEN: pMy = (char*)myldrOpen; break;
376 case iLDRCLOSE: pMy = (char*)myldrClose; break;
377 case iLDRQAPPTYPE: pMy = (char*)myLDRQAppType; break;
378
379 default:
380 kprintf(("rehookFunctions: Someone has added function without updating the switch! i=%d\n", i));
381 Int3();
382 return 2;
383 }
384
385 /* copy function prolog */
386 memcpy(callTab[i], (void*)_aProcTab[i].ulAddress, (size_t)cb);
387
388 /* jump from calltab to original function */
389 callTab[i][cb] = 0xE9; /* jmp */
390 *(unsigned*)&callTab[i][cb+1] = _aProcTab[i].ulAddress + cb - (unsigned)&callTab[i][cb+5];
391
392 /* jump from original function to my function - an cli could be needed here */
393 *(char*)_aProcTab[i].ulAddress = 0xE9; /* jmp */
394 *(unsigned*)(_aProcTab[i].ulAddress + 1) = (unsigned)pMy - (_aProcTab[i].ulAddress + 5);
395 }
396 else
397 {
398 /* !fatal! - this could never happen really... */
399 kprintf(("rehookFunctions: FATAL verify failed for procedure no.%d when rehooking it!\n",i));
400 Int3(); /* ipe - later! */
401 return 1;
402 }
403 }
404
405 return NO_ERROR;
406}
407
Note: See TracBrowser for help on using the repository browser.