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

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

Initial checkin of Win32k. (not tested & pe2lx not up-to-date!)

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