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

Last change on this file was 5086, checked in by bird, 25 years ago

Moved ldrCalls.h into the OS2Krnl.h tree as OS2KLDR.h.
Also moved the Ldr definitions from OS2Krnl.h and into OS2KLDR.h.

File size: 12.7 KB
RevLine 
[5086]1/* $Id: ldr.cpp,v 1.10 2001-02-10 11:11:45 bird Exp $
[847]2 *
[1467]3 * ldr.cpp - Loader helpers.
[847]4 *
5 * Copyright (c) 1999 knut St. osmundsen
6 *
[1678]7 * Project Odin Software License can be found in LICENSE.TXT
8 *
[847]9 */
10
11/*******************************************************************************
12* Defined Constants And Macros *
13*******************************************************************************/
14#define INCL_DOSERRORS
15#define INCL_NOPMAPI
[4164]16#define INCL_OS2KRNL_SEM
17#define INCL_OS2KRNL_PTDA
[5086]18#define INCL_OS2KRNL_LDR
[847]19
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#include <os2.h>
24
[4164]25#include "devSegDf.h"
[847]26#include "malloc.h"
27#include "new.h"
[1273]28#include <memory.h>
29#include <stdlib.h>
[1467]30#include <stddef.h>
[4164]31#include <string.h>
[1273]32
[847]33#include "log.h"
[4164]34#include "avl.h"
[1273]35#include <peexe.h>
36#include <exe386.h>
37#include "OS2Krnl.h"
[4164]38#include "ldr.h"
[1678]39#include "ModuleBase.h"
[1273]40#include "pe2lx.h"
[1512]41#include "options.h"
[847]42
43
44/*******************************************************************************
45* Global Variables *
46*******************************************************************************/
[4164]47static PAVLNODECORE pSFNRoot = NULL;
48static PAVLNODECORE pMTERoot = NULL;
[1467]49
[4164]50
51/*
52 * Loader State. (See ldr.h for more info.)
53 */
[4785]54ULONG ulLdrState = LDRSTATE_UNKNOWN;
[4164]55
56
57/*
[4785]58 * ldrOpen extention fix flag. (See ldr.h, myldrOpenPath.cpp and myldrOpen.cpp.)
59 */
60BOOL fldrOpenExtentionFix = FALSE;
61
62
63/*
[4164]64 * Pointer to the executable module being loaded.
65 * This pointer is set by ldrOpen and cleared by tkExecPgm.
66 * It's hence only valid at tkExecPgm time. (isLdrStateExecPgm() == TRUE).
67 */
68PMODULE pExeModule = NULL;
69
70
71/*
72 * Filehandle bitmap.
73 */
[1273]74unsigned char achHandleStates[MAX_FILE_HANDLES/8];
[847]75
76
[4164]77
78
[847]79/**
[1467]80 * Gets a module by the give hFile.
81 * @returns Pointer to module node. If not found NULL.
82 * @param hFile File handle of the module to be found.
83 * @sketch return a AVLGet on the pSFNRoot-tree.
84 * @status completely implemented.
85 * @author knut st. osmundsen
[847]86 */
[1467]87PMODULE getModuleBySFN(SFN hFile)
[847]88{
[1467]89 return (PMODULE)AVLGet(&pSFNRoot, (AVLKEY)hFile);
[847]90}
91
92
93/**
[1467]94 * Gets a module by the MTE.
95 * @returns Pointer to module node. If not found NULL.
[4164]96 * @param pMTE Pointer a Module Table Entry.
[1467]97 * @sketch Try find it in the MTE tree.
98 * IF not found THEN
99 * BEGIN
100 * DEBUG: validate pMTE pointer.
101 * Get the SFN from the MTE.
102 * IF found in the SFN-tree THEN
103 * BEGIN
104 * Update the pMTE in the node.
105 * Add the node to the MTE-tree.
106 * END
107 * ELSE return NULL
108 * END
109 * return pointer to module node.
110 * @status completely implemented.
111 * @author knut st. osmundsen
[847]112 */
[1467]113PMODULE getModuleByMTE(PMTE pMTE)
[847]114{
[2501]115 #if 0
116 /* Not 100% sure that this will work correctly! */
117 PMODULE pMod = (PMODULE)AVLGet(&pMTERoot, (AVLKEY)pMTE);
118 if (pMod == NULL)
[847]119 {
[2501]120 #ifdef DEBUG
121 if (pMTE <= (PMTE)0x10000)
122 {
123 kprintf(("getModuleByMTE: invalid pMTE pointer - %#8x\n", pMTE));
124 return NULL;
125 }
126 #endif
127 pMod = (PMODULE)AVLGet(&pSFNRoot, (AVLKEY)pMTE->mte_sfn);
128 if (pMod != NULL)
129 {
130 pMod->coreMTE.Key = (AVLKEY)pMTE;
131 pMod->fFlags |= MOD_FLAGS_IN_MTETREE;
132 AVLInsert(&pMTERoot, (PAVLNODECORE)((unsigned)pMod + offsetof(MODULE, coreMTE)));
133 }
[847]134 }
[2501]135 else
136 pMod = (PMODULE)((unsigned)pMod - offsetof(MODULE, coreMTE));
137 return pMod;
138 #else
139 /* Use this for the time being. */
140 #ifdef DEBUG
141 if (pMTE <= (PMTE)0x10000)
142 {
143 kprintf(("getModuleByMTE: invalid pMTE pointer - %#8x\n", pMTE));
144 return NULL;
145 }
[1467]146 #endif
[2501]147 if (GetState(pMTE->mte_sfn) == HSTATE_OUR)
148 return (PMODULE)AVLGet(&pSFNRoot, (AVLKEY)pMTE->mte_sfn);
149
150 return NULL;
151 #endif
[847]152}
153
154
155/**
[4164]156 * Gets a module by the hMTE.
157 * @returns Pointer to module node. If not found NULL.
158 * @param hMTE Handle to a Module Table Entry.
159 * @sketch Convert hMte to an pMTE (pointer to MTE).
160 * Call getModuleByMTE with MTE pointer.
161 * @status completely implemented.
162 * @author knut st. osmundsen
163 */
164PMODULE getModuleByhMTE(HMTE hMTE)
165{
166 PMTE pMTE;
167
168 pMTE = ldrValidateMteHandle(hMTE);
169 if (pMTE != NULL)
170 return getModuleByMTE(pMTE);
171
172 return NULL;
173}
174
175
176/**
[1467]177 * Get a module by filename.
178 * @returns Pointer to module node. If not found NULL.
179 * @param pszFilename Pointer to the filename which we are search by.
180 * @sketch Not implemented.
181 * @status Stub.
182 * @author knut st. osmundsen
[847]183 */
[1467]184PMODULE getModuleByFilename(PCSZ pszFilename)
[847]185{
[1467]186 pszFilename = pszFilename;
187 return NULL;
[847]188}
189
190
191/**
[1467]192 * Adds a module to the SFN-tree, if pMTE is not NULL it is added to the MTE-tree too.
193 * @returns NO_ERROR on success. Appropriate errorcode on failiure.
194 * @param hFile System file number for the module.
195 * @param pMTE Pointer to MTE. NULL is valid.
196 * @param fFlags Type flags for the fFlags field in the node.
[1678]197 * @param pModObj Pointer to module object.
[1467]198 * @sketch DEBUG: check that the module doesn't exists and parameter check.
199 * (try) Allocate a new node. (return errorcode on failure)
200 * Fill in the node.
201 * Add the node to the SFN-tree.
202 * IF valid MTE pointer THEN add it to the MTE tree and set the in MTE-tree flag.
203 * return successfully.
204 * @status completely implemented.
205 * @author knut st. osmundsen
[847]206 */
[1678]207ULONG addModule(SFN hFile, PMTE pMTE, ULONG fFlags, ModuleBase *pModObj)
[847]208{
[1467]209 PMODULE pMod;
210 #ifdef DEBUG
211 if (AVLGet(&pSFNRoot, (AVLKEY)hFile) != NULL)
212 kprintf(("addModule: Module allready present in the SFN-tree!\n"));
213 if (hFile == 0)
214 {
215 kprintf(("addModule: invalid parameter: hFile = 0\n"));
216 return ERROR_INVALID_PARAMETER;
217 }
[2501]218 if ((fFlags & MOD_TYPE_MASK) == 0 || (fFlags & ~MOD_TYPE_MASK) != 0UL)
[1467]219 {
220 kprintf(("addModule: invalid parameter: fFlags = 0x%#8x\n", fFlags));
221 return ERROR_INVALID_PARAMETER;
222 }
223 #endif
[847]224
[1467]225 /* try allocate memory for the node. */
226 pMod = (PMODULE)malloc(sizeof(MODULE));
227 if (pMod == NULL)
228 {
229 kprintf(("addModule: out of memory!\n"));
230 return ERROR_NOT_ENOUGH_MEMORY;
231 }
[847]232
[1467]233 /* fill in the module node. */
234 pMod->coreKey.Key = (AVLKEY)hFile;
235 pMod->hFile = hFile;
236 pMod->pMTE = pMTE;
237 pMod->fFlags = fFlags;
[1678]238 pMod->Data.pModule = pModObj;
[847]239
[1467]240 /* insert the module node into the tree(s) */
241 AVLInsert(&pSFNRoot, (PAVLNODECORE)pMod);
242 if (pMTE != NULL)
243 {
244 pMod->coreMTE.Key = (AVLKEY)pMTE;
245 pMod->fFlags |= MOD_FLAGS_IN_MTETREE;
246 AVLInsert(&pMTERoot, (PAVLNODECORE)((unsigned)pMod + offsetof(MODULE, coreMTE)));
247 }
[847]248
[1467]249 return NO_ERROR;
[847]250}
251
252
253/**
[1467]254 * Removes and frees a module node (including the data pointer).
255 * @returns NO_ERROR on success. Appropriate error code on failure.
256 * @param hFile System filehandle of the module.
257 * @sketch Remove the node from the SFN-tree.
258 * IF present in the MTE-tree THEN remove it from the tree.
259 * Delete the datapointer.
260 * Free the module node.
261 * return successfully.
262 * @status completely implemented.
263 * @author knut st. osmundsen
[847]264 */
[1467]265ULONG removeModule(SFN hFile)
[847]266{
[1467]267 PMODULE pMod = (PMODULE)AVLRemove(&pSFNRoot, (AVLKEY)hFile);
268 if (pMod == NULL)
269 {
270 kprintf(("removeModule: Module not found! hFile=%#4x\n", hFile));
271 return ERROR_INVALID_PARAMETER;
272 }
[847]273
[1467]274 /* In MTE-tree too? */
275 if (pMod->fFlags & MOD_FLAGS_IN_MTETREE)
276 {
277 if (AVLRemove(&pMTERoot, (AVLKEY)pMod->pMTE) == NULL)
278 {
279 kprintf(("removeModule: MOD_FLAGS_IN_MTETREE set but AVLRemove returns NULL\n"));
280 }
281 }
[847]282
[1467]283 /* Delete the datapointer. */
284 switch (pMod->fFlags & MOD_TYPE_MASK)
285 {
286 case MOD_TYPE_PE2LX:
287 delete pMod->Data.pPe2Lx;
288 break;
[4164]289/*
[1467]290 case MOD_TYPE_ELF2LX:
[4164]291 break;
292*/
293#ifdef DEBUG
[1467]294 default:
295 kprintf(("removeModule: Unknown type, %#x\n", pMod->fFlags & MOD_TYPE_MASK));
[4164]296#endif
[1467]297 }
[847]298
[1467]299 /* Free the module node. */
300 free(pMod);
[847]301
302 return NO_ERROR;
303}
304
305
306/**
[4164]307 * Gets the path of the executable being executed.
308 * @returns Pointer to pszPath on success. Path has _NOT_ a trailing slash.
309 * NULL pointer on error.
310 * @param pszPath Pointer to path buffer. Expects CCHMAXPATH length.
311 * @param fExecChild Use hMTE of the PTDAExecChild if present.
312 * @sketch
313 * @status completely implemented.
314 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
315 * @remark The path from the pExeModule might not be fully qualified.
316 */
317PSZ ldrGetExePath(PSZ pszPath, BOOL fExecChild)
318{
319 PCSZ pszFilename;
320 PCSZ psz;
321
322 #if 0 /* getFilename not implemented */
323 if (pExeModule != NULL)
324 /*
325 * We have the executable object pointer. Let's use it!
326 */
327 pszFilename = pExeModule->Data.pModule->getFilename();
328 else
329 #endif
330 {
331 /*
332 * Get the hMTE for the executable using the pPTDAExecChild
333 * Then get the pMTE, and access the smte_path to get a pointer to the executable path.
334 */
335 PPTDA pPTDACur; /* Pointer to the current (system context) PTDA */
336 PPTDA pPTDA; /* PTDA in question. */
337 HMTE hMTE = NULLHANDLE; /* Modulehandle of the executable module. */
338 PMTE pMTE; /* Pointer to ModuleTableEntry of the executable module. */
339
340 /*
341 * Get the current PTDA. (Fail if this call failes.)
342 * IF pPTDAExecChild isn't NULL THEN get hMTE for that.
343 * IF no pPTDAExecChild THEN get hMte for the current PTDA.
344 */
345 pPTDACur = ptdaGetCur();
346 if (pPTDACur != NULL)
347 {
348 pPTDA = ptdaGet_pPTDAExecChild(pPTDACur);
349 if (pPTDA != NULL && fExecChild)
350 hMTE = ptdaGet_ptda_module(pPTDA);
351 if (hMTE == NULLHANDLE)
352 hMTE = ptdaGet_ptda_module(pPTDACur);
353 }
354 else
355 { /* Not called at task time? No current task! */
356 kprintf(("ldrGetExePath: Failed to get current PTDA.\n"));
357 return NULL;
358 }
359
360 /* fail if hMTE is NULLHANDLE ie. not found / invalid */
361 if (hMTE == NULLHANDLE)
362 {
363 kprintf(("ldrGetExePath: Failed to get hMTE from the PTDAs.\n"));
364 return NULL;
365 }
366
367 /* get the pMTE for this hMTE */
368 pMTE = ldrASMpMTEFromHandle(hMTE);
369 if (pMTE == NULL)
370 {
371 kprintf(("ldrGetExePath: ldrASMpMTEFromHandle failed for hMTE=0x%04.\n", hMTE));
372 return NULL;
373 }
374 if (pMTE->mte_swapmte == NULL) /* paranoia */
375 {
376 kprintf(("ldrGetExePath: mte_swapmte is NULL.\n"));
377 return NULL;
378 }
379
380 /* take the filename from the swappable MTE */
381 pszFilename = pMTE->mte_swapmte->smte_path;
382 if (pszFilename == NULL)
383 {
384 kprintf(("ldrGetExePath: smte_path is NULL.\n"));
385 return NULL;
386 }
387 }
388
389 /* paranoia... */
390 if (*pszFilename == '\0')
391 {
392 kprintf(("ldrGetExePath: pszFilename is empty!\n"));
393 return NULL;
394 }
395
396 /*
397 * Skip back over the filename. (stops pointing at the slash or ':')
398 */
399 psz = pszFilename + strlen(pszFilename)-1;
400 while (psz >= pszFilename && *psz != '\\' && *psz != '/' && *psz != ':')
401 psz--;
402
403 /*
404 * If no path the fail.
405 */
406 if (psz <= pszFilename)
407 {
408 kprintf(("ldrGetExePath: Exepath is empty.\n"));
409 return NULL;
410 }
411
412 /*
413 * Copy path and return.
414 */
415 memcpy(pszPath, pszFilename, psz - pszFilename);
416 pszPath[psz - pszFilename] = '\0';
417 return pszPath;
418}
419
420
421/**
[847]422 * Initiate the loader "sub-system".
423 * @returns NO_ERROR on success. !0 on error.
424 */
425ULONG ldrInit(void)
426{
427 int rc = NO_ERROR;
428
429 /* init state table */
[1273]430 memset(&achHandleStates[0], 0, sizeof(achHandleStates));
[847]431
[1467]432 /* init the tree roots */
433 pSFNRoot = NULL;
434 pMTERoot = NULL;
[847]435
[1678]436 /* ModuleBase logging. */
437 ModuleBase::ulInfoLevel = options.ulInfoLevel;
[1512]438
[847]439 return rc;
440}
441
Note: See TracBrowser for help on using the repository browser.