source: trunk/src/win32k/ldr/ldr.cpp@ 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.4 KB
Line 
1/* $Id: ldr.cpp,v 1.1 1999-09-06 02:20:00 bird Exp $
2 *
3 * ldr.cpp - Loader helper functions a structures.
4 *
5 * Copyright (c) 1999 knut St. osmundsen
6 *
7 */
8
9/*******************************************************************************
10* Defined Constants And Macros *
11*******************************************************************************/
12#define INCL_DOSERRORS
13#define INCL_NOPMAPI
14
15
16/*******************************************************************************
17* Header Files *
18*******************************************************************************/
19#include <os2.h>
20#include <string.h>
21
22#include "malloc.h"
23#include "new.h"
24#include "log.h"
25#include "pefile.h"
26#include "lx.h"
27#include "ldr.h"
28
29
30/*******************************************************************************
31* Global Variables *
32*******************************************************************************/
33unsigned char ahStates[MAX_FILE_HANDLES/4];
34UNCERTAIN ahUncertain[MAX_UNCERTAIN_FILES];
35PPENODE pPE;
36
37
38/*******************************************************************************
39* Internal Functions *
40*******************************************************************************/
41static PPENODE findNodePtr2(PPENODE pRoot, const char *pszFilename);
42static ULONG freeNode(PPENODE pNode);
43static ULONG depth(PPENODE pNode);
44
45
46/**
47 * Get a free entry in the ahUncertain table.
48 * @returns Index to free entry in the ahUncertain table.
49 */
50ULONG getFreeUncertainEntry(void)
51{
52 ULONG i;
53
54 i = 0;
55 while (i < MAX_UNCERTAIN_FILES && ahUncertain[i].hFile != 0xFFFF)
56 i++;
57
58 return i < MAX_UNCERTAIN_FILES ? i : -1;
59}
60
61
62/**
63 * Free uncertain entry.
64 * Mark entry with hFile in the uncertain table as unused
65 * @returns NO_ERROR on success, -1 on error.
66 * @param hFile Filehandle (key) to free.
67 */
68ULONG freeUncertainEntry(SFN hFile)
69{
70 int i;
71 int rc;
72
73 i = 0;
74 while (i < MAX_UNCERTAIN_FILES && ahUncertain[i].hFile != hFile)
75 i++;
76
77 if (i < MAX_UNCERTAIN_FILES && ahUncertain[i].hFile == hFile)
78 {
79 ahUncertain[i].hFile = 0xFFFF;
80 ahUncertain[i].offsetNEHdr = 0;
81 ahUncertain[i].fMZ = 0;
82 ahUncertain[i].fPE = 0;
83 free(ahUncertain[i].pszName);
84 ahUncertain[i].pszName = NULL;
85 rc = NO_ERROR;
86 }
87 else
88 rc = -1;
89 return rc;
90}
91
92
93/**
94 * Find the uncertain entry for hFile
95 * @returns Index into ahUncertain if found. ~0UL on error.
96 * @param hFile Filehandle (key) to find.
97 */
98ULONG findUncertainEntry(SFN hFile)
99{
100 int i = 0;
101 while (i < MAX_UNCERTAIN_FILES && ahUncertain[i].hFile != hFile)
102 i++;
103
104 return i < MAX_UNCERTAIN_FILES ? (ULONG)i : ~0UL;
105}
106
107
108/**
109 * Inserts a PENode into the pPE tree.
110 * @returns NO_ERROR on success. !0 on error.
111 * @param pNode Pointer to node to insert.
112 */
113ULONG insertNode(PPENODE pNode)
114{
115 int level;
116 PPENODE pPrev;
117 PPENODE pTmp;
118
119 if (pPE == NULL)
120 {
121 pPE = pNode;
122 pNode->left = pNode->right = NULL;
123 }
124 else
125 {
126 level = 0;
127 pPrev = NULL;
128 pTmp = pPE;
129 while (pTmp != NULL)
130 {
131 level = 0;
132 pPrev = pTmp;
133 pTmp = AdjustKey(pNode->hFile) < AdjustKey(pTmp->hFile) ? pTmp->left : pTmp->right;
134 }
135
136 if (pNode->hFile != pPrev->hFile)
137 {
138 if (AdjustKey(pNode->hFile) < AdjustKey(pPrev->hFile))
139 pPrev->left = pNode;
140 else
141 pPrev->right = pNode;
142 pNode->left = pNode->right = NULL;
143 }
144 else
145 return -1;
146 }
147
148 return NO_ERROR;
149}
150
151
152/**
153 * Deletes a node from the pPE tree.
154 * @returns NO_ERROR on success. !0 on error.
155 * @param key Filehandle, which is the key.
156 */
157ULONG deleteNode(SFN key)
158{
159 int level,level2;
160 ULONG rc;
161 PPENODE pTmp,pTmp2;
162 PPENODE pPrev,pPrev2;
163 int left;
164
165 if (pPE != NULL)
166 {
167 /* find node to delete */
168 level = 1;
169 pPrev = NULL;
170 pTmp = pPE;
171 while (pTmp != NULL && key != pTmp->hFile)
172 {
173 pPrev = pTmp;
174 pTmp = (left = (AdjustKey(key) < AdjustKey(pTmp->hFile))) == TRUE ? pTmp->left : pTmp->right;
175 level ++;
176 }
177
178 if (pTmp != NULL)
179 {
180 /*found it: pTmp -> node to delete - pPrev -> parent node*/
181 level--;
182 rc = -1;
183 if (pTmp->left != NULL && pTmp->right != NULL)
184 {
185 /* hard case - fetch the leftmost node in the right subtree */
186 level2 = level;
187 pPrev2 = pTmp;
188 pTmp2 = pTmp->right;
189 while (pTmp2->left != NULL)
190 {
191 pPrev2 = pTmp2;
192 pTmp2 = pTmp2->left;
193 level2++;
194 }
195 /* pTmp2 -> new root - pPrev2 -> parent node */
196
197 /* left child of pTmp2 */
198 pTmp2->left = pTmp->left;
199
200 /* parent of pTmp2 and pTmp2->right */
201 if (pPrev2 != pTmp)
202 {
203 pPrev2->left = pTmp2->right;
204 pTmp2->right = pTmp->right;
205 }
206 //else pTmp2->right = pTmp2->right;
207
208 /* link in pTmp2 */
209 if (pTmp != pPE)
210 {
211 if (left)
212 pPrev->left = pTmp2;
213 else
214 pPrev->right = pTmp2;
215 }
216 else
217 pPE = pTmp2;
218 rc = NO_ERROR;
219 }
220
221 /* leaf */
222 if (rc!=0 && pTmp->left == NULL && pTmp->right == NULL)
223 {
224 if (pTmp != pPE)
225 {
226 if (left)
227 pPrev->left = NULL;
228 else
229 pPrev->right = NULL;
230 }
231 else
232 pPE = NULL;
233 rc = NO_ERROR;
234 }
235
236 /* left is NULL */
237 if (rc!=0 && pTmp->left == NULL && pTmp->right != NULL)
238 {
239 /* move up right node */
240 if (pTmp != pPE)
241 {
242 if (left)
243 pPrev->left = pTmp->right;
244 else
245 pPrev->right = pTmp->right;
246 }
247 else
248 pPE = pTmp->right;
249 rc = NO_ERROR;
250 }
251
252 /* right is NULL */
253 if (rc!=0 && pTmp->left != NULL && pTmp->right == NULL)
254 {
255 /* move up left node */
256 if (pTmp != pPE)
257 {
258 if (left)
259 pPrev->left = pTmp->left;
260 else
261 pPrev->right = pTmp->left;
262 }
263 else
264 pPE = pTmp->left;
265 rc = NO_ERROR;
266 }
267
268 /* free node */
269 if (rc == NO_ERROR)
270 rc = freeNode( pTmp );
271 }
272 else
273 rc = 1; //not found
274 }
275 else
276 rc = 1; //not found
277 return rc;
278}
279
280
281/**
282 * Get the pointer to a node in the pPE tree.
283 * @returns Pointer to node on success. NULL if not found or error occured.
284 * @param key Filehandle, which is the key for the pPE tree.
285 */
286PPENODE getNodePtr(SFN key)
287{
288 PPENODE pTmp = pPE;
289 int level = 1;
290 while (pTmp != NULL && pTmp->hFile != key)
291 {
292 pTmp = AdjustKey(key) < AdjustKey(pTmp->hFile) ? pTmp->left : pTmp->right;
293 level++;
294 }
295 return pTmp;
296}
297
298
299/**
300 * Find a PENode by filename in the node tree.
301 * @returns Pointer to PENode if found, NULL if not found.
302 * @param pszFilename Pointer to filename.
303 */
304PPENODE findNodePtr(const char *pszFilename)
305{
306 /*depth first search thru the whole tree */
307 return findNodePtr2(pPE, pszFilename);
308}
309
310
311/**
312 * Find a PENode by filename in the given tree.
313 * Depth first search thru the whole tree.
314 * @returns Pointer to matching PENode.
315 * @param pRoot Tree root.
316 * @param pszFilename Pointer to filename.
317 * @remark sub-function of findNodePtr.
318 */
319static PPENODE findNodePtr2(PPENODE pRoot, const char *pszFilename)
320{
321 PPENODE pNode = NULL;
322
323 /*depth first search thru the whole tree */
324 if ( pRoot == NULL || pRoot->lxfile.queryIsModuleName(pszFilename))
325 return pRoot;
326
327 //search subtrees
328 if (pRoot->left != NULL)
329 pNode = findNodePtr2(pRoot->left,pszFilename);
330 if (pNode == NULL && pRoot->right != NULL)
331 pNode = findNodePtr2(pRoot->right,pszFilename);
332 return pNode;
333}
334
335
336/**
337 * Allocate memory for a PENode.
338 * @returns Pointer to new PENode on success. NULL pointer on error.
339 */
340PPENODE allocateNode(void)
341{
342 PPENODE pNode;
343
344 pNode = new PENODE;
345 if (pNode == NULL)
346 kprintf(("allocateNode: malloc returned an NULL-pointer\n"));
347
348 return pNode;
349}
350
351
352/**
353 * Frees node.
354 * @returns NO_ERROR on success.
355 * @param pNode Pointer to node which is to be freed.
356 */
357static ULONG freeNode(PPENODE pNode)
358{
359 if (pNode != NULL)
360 delete pNode;
361
362 return NO_ERROR;
363}
364
365
366/**
367 * Gets the depth of the pPE tree.
368 * @returns Number of levels in the the pPE tree.
369 */
370ULONG depthPE(void)
371{
372 return depth(pPE);
373}
374
375
376
377/**
378 * Gets the depth of the pPE tree.
379 * @returns Number of levels in the the pPE tree.
380 * @param pNode Node to start at. (root node...)
381 */
382static ULONG depth(PPENODE pNode)
383{
384 if (pNode != NULL)
385 {
386 int l, r;
387 l = depth(pNode->left);
388 r = depth(pNode->right);
389 return 1 + (l > r ? l : r);
390 }
391 else
392 return 0;
393}
394
395
396/**
397 * Initiate the loader "sub-system".
398 * @returns NO_ERROR on success. !0 on error.
399 */
400ULONG ldrInit(void)
401{
402 int rc = NO_ERROR;
403 int i;
404
405 /* init state table */
406 for (i = 0; i < MAX_FILE_HANDLES/4; i++)
407 ahStates[i] = 0;
408
409 /* init uncertain files */
410 for (i = 0; i < MAX_UNCERTAIN_FILES; i++)
411 {
412 ahUncertain[i].hFile = 0xFFFF;
413 ahUncertain[i].offsetNEHdr = 0;
414 ahUncertain[i].fMZ = 0;
415 ahUncertain[i].fPE = 0;
416 ahUncertain[i].pszName = NULL;
417 }
418
419 /* init pPEFiles* */
420 pPE = NULL;
421
422 return rc;
423}
424
Note: See TracBrowser for help on using the repository browser.