source: trunk/src/win32k/ldr/ldr.cpp@ 1273

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

Pe2Lx rewrite changes in win32k.
Pluss some makefile/depend changes.

File size: 8.7 KB
Line 
1/* $Id: ldr.cpp,v 1.2 1999-10-14 01:25:38 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
21#include "malloc.h"
22#include "new.h"
23#include <memory.h>
24#include <stdlib.h>
25
26#include "log.h"
27#include <peexe.h>
28#include <exe386.h>
29#include "OS2Krnl.h"
30#include "pe2lx.h"
31#include "ldr.h"
32
33
34/*******************************************************************************
35* Global Variables *
36*******************************************************************************/
37PPENODE pPE;
38unsigned char achHandleStates[MAX_FILE_HANDLES/8];
39
40
41/*******************************************************************************
42* Internal Functions *
43*******************************************************************************/
44static PPENODE findNodePtr2(PPENODE pRoot, const char *pszFilename);
45static ULONG depth(PPENODE pNode);
46
47
48/**
49 * Inserts a PENode into the pPE tree.
50 * @returns NO_ERROR on success. !0 on error.
51 * @param pNode Pointer to node to insert.
52 */
53ULONG insertNode(PPENODE pNode)
54{
55 int level;
56 PPENODE pPrev;
57 PPENODE pTmp;
58
59 if (pPE == NULL)
60 {
61 pPE = pNode;
62 pNode->left = pNode->right = NULL;
63 }
64 else
65 {
66 level = 0;
67 pPrev = NULL;
68 pTmp = pPE;
69 while (pTmp != NULL)
70 {
71 level = 0;
72 pPrev = pTmp;
73 pTmp = AdjustKey(pNode->hFile) < AdjustKey(pTmp->hFile) ? pTmp->left : pTmp->right;
74 }
75
76 if (pNode->hFile != pPrev->hFile)
77 {
78 if (AdjustKey(pNode->hFile) < AdjustKey(pPrev->hFile))
79 pPrev->left = pNode;
80 else
81 pPrev->right = pNode;
82 pNode->left = pNode->right = NULL;
83 }
84 else
85 return -1;
86 }
87
88 return NO_ERROR;
89}
90
91
92/**
93 * Deletes a node from the pPE tree.
94 * @returns NO_ERROR on success. !0 on error.
95 * @param key Filehandle, which is the key.
96 */
97ULONG deleteNode(SFN key)
98{
99 int level,level2;
100 ULONG rc;
101 PPENODE pTmp,pTmp2;
102 PPENODE pPrev,pPrev2;
103 int left;
104
105 if (pPE != NULL)
106 {
107 /* find node to delete */
108 level = 1;
109 pPrev = NULL;
110 pTmp = pPE;
111 while (pTmp != NULL && key != pTmp->hFile)
112 {
113 pPrev = pTmp;
114 pTmp = (left = (AdjustKey(key) < AdjustKey(pTmp->hFile))) == TRUE ? pTmp->left : pTmp->right;
115 level ++;
116 }
117
118 if (pTmp != NULL)
119 {
120 /*found it: pTmp -> node to delete - pPrev -> parent node*/
121 level--;
122 rc = -1;
123 if (pTmp->left != NULL && pTmp->right != NULL)
124 {
125 /* hard case - fetch the leftmost node in the right subtree */
126 level2 = level;
127 pPrev2 = pTmp;
128 pTmp2 = pTmp->right;
129 while (pTmp2->left != NULL)
130 {
131 pPrev2 = pTmp2;
132 pTmp2 = pTmp2->left;
133 level2++;
134 }
135 /* pTmp2 -> new root - pPrev2 -> parent node */
136
137 /* left child of pTmp2 */
138 pTmp2->left = pTmp->left;
139
140 /* parent of pTmp2 and pTmp2->right */
141 if (pPrev2 != pTmp)
142 {
143 pPrev2->left = pTmp2->right;
144 pTmp2->right = pTmp->right;
145 }
146 //else pTmp2->right = pTmp2->right;
147
148 /* link in pTmp2 */
149 if (pTmp != pPE)
150 {
151 if (left)
152 pPrev->left = pTmp2;
153 else
154 pPrev->right = pTmp2;
155 }
156 else
157 pPE = pTmp2;
158 rc = NO_ERROR;
159 }
160
161 /* leaf */
162 if (rc!=0 && pTmp->left == NULL && pTmp->right == NULL)
163 {
164 if (pTmp != pPE)
165 {
166 if (left)
167 pPrev->left = NULL;
168 else
169 pPrev->right = NULL;
170 }
171 else
172 pPE = NULL;
173 rc = NO_ERROR;
174 }
175
176 /* left is NULL */
177 if (rc!=0 && pTmp->left == NULL && pTmp->right != NULL)
178 {
179 /* move up right node */
180 if (pTmp != pPE)
181 {
182 if (left)
183 pPrev->left = pTmp->right;
184 else
185 pPrev->right = pTmp->right;
186 }
187 else
188 pPE = pTmp->right;
189 rc = NO_ERROR;
190 }
191
192 /* right is NULL */
193 if (rc!=0 && pTmp->left != NULL && pTmp->right == NULL)
194 {
195 /* move up left node */
196 if (pTmp != pPE)
197 {
198 if (left)
199 pPrev->left = pTmp->left;
200 else
201 pPrev->right = pTmp->left;
202 }
203 else
204 pPE = pTmp->left;
205 rc = NO_ERROR;
206 }
207
208 /* free node */
209 if (rc == NO_ERROR)
210 rc = freeNode( pTmp );
211 }
212 else
213 rc = 1; //not found
214 }
215 else
216 rc = 1; //not found
217 return rc;
218}
219
220
221/**
222 * Get the pointer to a node in the pPE tree.
223 * @returns Pointer to node on success. NULL if not found or error occured.
224 * @param key Filehandle, which is the key for the pPE tree.
225 */
226PPENODE getNodePtr(SFN key)
227{
228 PPENODE pTmp = pPE;
229 int level = 1;
230 while (pTmp != NULL && pTmp->hFile != key)
231 {
232 pTmp = AdjustKey(key) < AdjustKey(pTmp->hFile) ? pTmp->left : pTmp->right;
233 level++;
234 }
235 return pTmp;
236}
237
238
239/**
240 * Find a PENode by filename in the node tree.
241 * @returns Pointer to PENode if found, NULL if not found.
242 * @param pszFilename Pointer to filename.
243 */
244PPENODE findNodePtr(const char *pszFilename)
245{
246 /*depth first search thru the whole tree */
247 return findNodePtr2(pPE, pszFilename);
248}
249
250
251/**
252 * Find a PENode by filename in the given tree.
253 * Depth first search thru the whole tree.
254 * @returns Pointer to matching PENode.
255 * @param pRoot Tree root.
256 * @param pszFilename Pointer to filename.
257 * @remark sub-function of findNodePtr.
258 */
259static PPENODE findNodePtr2(PPENODE pRoot, const char *pszFilename)
260{
261 PPENODE pNode = NULL;
262
263 /*depth first search thru the whole tree */
264 if (pRoot == NULL || pRoot->pPe2Lx->queryIsModuleName(pszFilename))
265 return pRoot;
266
267 //search subtrees
268 if (pRoot->left != NULL)
269 pNode = findNodePtr2(pRoot->left,pszFilename);
270 if (pNode == NULL && pRoot->right != NULL)
271 pNode = findNodePtr2(pRoot->right,pszFilename);
272 return pNode;
273}
274
275
276/**
277 * Allocate memory for a PENode.
278 * @returns Pointer to new PENode on success. NULL pointer on error.
279 */
280PPENODE allocateNode(void)
281{
282 PPENODE pNode;
283
284 pNode = new PENODE;
285 if (pNode == NULL)
286 kprintf(("allocateNode: new returned a NULL-pointer\n"));
287
288 return pNode;
289}
290
291
292/**
293 * Frees node.
294 * @returns NO_ERROR on success.
295 * @param pNode Pointer to node which is to be freed.
296 */
297ULONG freeNode(PPENODE pNode)
298{
299 if (pNode != NULL)
300 delete pNode;
301
302 return NO_ERROR;
303}
304
305
306/**
307 * Gets the depth of the pPE tree.
308 * @returns Number of levels in the the pPE tree.
309 */
310ULONG depthPE(void)
311{
312 return depth(pPE);
313}
314
315
316
317/**
318 * Gets the depth of the pPE tree.
319 * @returns Number of levels in the the pPE tree.
320 * @param pNode Node to start at. (root node...)
321 */
322static ULONG depth(PPENODE pNode)
323{
324 if (pNode != NULL)
325 {
326 int l, r;
327 l = depth(pNode->left);
328 r = depth(pNode->right);
329 return 1 + (l > r ? l : r);
330 }
331 else
332 return 0;
333}
334
335
336/**
337 * Initiate the loader "sub-system".
338 * @returns NO_ERROR on success. !0 on error.
339 */
340ULONG ldrInit(void)
341{
342 int rc = NO_ERROR;
343 int i;
344
345 /* init state table */
346 memset(&achHandleStates[0], 0, sizeof(achHandleStates));
347
348 /* init pPEFiles* */
349 pPE = NULL;
350
351 return rc;
352}
353
Note: See TracBrowser for help on using the repository browser.