| 1 | /* $Id: myldrOpenPath.cpp,v 1.4 2000-12-11 06:30:59 bird Exp $ | 
|---|
| 2 | * | 
|---|
| 3 | * myldrOpenPath - ldrOpenPath used to open executables we'll override | 
|---|
| 4 | * this to altern the search path for DLLs. | 
|---|
| 5 | * | 
|---|
| 6 | * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no) | 
|---|
| 7 | * | 
|---|
| 8 | * Project Odin Software License can be found in LICENSE.TXT | 
|---|
| 9 | * | 
|---|
| 10 | */ | 
|---|
| 11 |  | 
|---|
| 12 | /******************************************************************************* | 
|---|
| 13 | *   Defined Constants And Macros                                               * | 
|---|
| 14 | *******************************************************************************/ | 
|---|
| 15 | #define INCL_DOSERRORS | 
|---|
| 16 | #define INCL_NOPMAPI | 
|---|
| 17 | #define INCL_OS2KRNL_TCB | 
|---|
| 18 | #define INCL_OS2KRNL_PTDA | 
|---|
| 19 |  | 
|---|
| 20 | /******************************************************************************* | 
|---|
| 21 | *   Header Files                                                               * | 
|---|
| 22 | *******************************************************************************/ | 
|---|
| 23 | #include <os2.h> | 
|---|
| 24 |  | 
|---|
| 25 | #include <memory.h> | 
|---|
| 26 | #include <stdlib.h> | 
|---|
| 27 |  | 
|---|
| 28 | #include "devSegDf.h"                   /* Win32k segment definitions. */ | 
|---|
| 29 | #include "log.h" | 
|---|
| 30 | #include "dev32.h" | 
|---|
| 31 | #include "dev32hlp.h" | 
|---|
| 32 | #include <peexe.h> | 
|---|
| 33 | #include <exe386.h> | 
|---|
| 34 | #include "OS2Krnl.h" | 
|---|
| 35 | #include "avl.h" | 
|---|
| 36 | #include "ldrCalls.h" | 
|---|
| 37 | #include "ldr.h" | 
|---|
| 38 | #include "ModuleBase.h" | 
|---|
| 39 | #include "options.h" | 
|---|
| 40 |  | 
|---|
| 41 |  | 
|---|
| 42 | /** | 
|---|
| 43 | * ldrOpenPath. | 
|---|
| 44 | * myldrOpenPath - opens file eventually searching loader specific paths | 
|---|
| 45 | * | 
|---|
| 46 | * @returns   OS2 return code. | 
|---|
| 47 | *            plv->lv_sfn  is set to filename handle. | 
|---|
| 48 | * @param     pachFilename  Pointer to modulename. Not zero terminated! | 
|---|
| 49 | * @param     cchFilename   Modulename length. | 
|---|
| 50 | * @param     plv           Loader local variables? (Struct from KERNEL.SDF) | 
|---|
| 51 | * @param     pful          Pointer to flags which are passed on to ldrOpen. | 
|---|
| 52 | * @param     lLibPath      New parameter in build 14053() | 
|---|
| 53 | *                          ldrGetMte calls with 1 | 
|---|
| 54 | *                          ldrOpenNewExe calls with 3 | 
|---|
| 55 | *                          This is compared to the initial libpath index. | 
|---|
| 56 | *                              The libpath index is: | 
|---|
| 57 | *                                  BEGINLIBPATH    1 | 
|---|
| 58 | *                                  LIBPATH         2 | 
|---|
| 59 | *                                  ENDLIBPATH      3 | 
|---|
| 60 | *                              The initial libpath index is either 1 or 2. | 
|---|
| 61 | *                          Currently we'll ignore it. (I don't know why ldrGetMte calls ldrOpenPath...) | 
|---|
| 62 | * | 
|---|
| 63 | * @sketch | 
|---|
| 64 | * This is roughly what the original ldrOpenPath does: | 
|---|
| 65 | *      Save pTCBCur->TCBFailErr. | 
|---|
| 66 | *      if !CLASS_GLOBAL or miniifs then | 
|---|
| 67 | *          ldrOpen(pachFilename) | 
|---|
| 68 | *      else | 
|---|
| 69 | *          if beglibpath != NULL then path = 1 else path = 2 | 
|---|
| 70 | *          if (lLibPath < path) | 
|---|
| 71 | *              return ERROR_FILE_NOT_FOUND; (2) | 
|---|
| 72 | *          Allocate buffer. | 
|---|
| 73 | *          loop until no more libpath elements | 
|---|
| 74 | *              get next libpath element and add it to the modname. | 
|---|
| 75 | *              try open the modname | 
|---|
| 76 | *              if successfull then break the loop. | 
|---|
| 77 | *          endloop | 
|---|
| 78 | *          Free buffer. | 
|---|
| 79 | *      endif | 
|---|
| 80 | *      Restore pTCBCur->TCBFailErr. | 
|---|
| 81 | * @remark    This function will change the "Loader state". | 
|---|
| 82 | * | 
|---|
| 83 | */ | 
|---|
| 84 | ULONG LDRCALL myldrOpenPath(       /* retd  0x14 */ | 
|---|
| 85 | PCHAR       pachFilename,       /* ebp + 0x08 */ | 
|---|
| 86 | USHORT      cchFilename,        /* ebp + 0x0c */ | 
|---|
| 87 | ldrlv_t *   plv,                /* ebp + 0x10 */ | 
|---|
| 88 | PULONG      pful,               /* ebp + 0x14 */ | 
|---|
| 89 | ULONG       lLibPath            /* ebp + 0x18 */ | 
|---|
| 90 | ) | 
|---|
| 91 | { | 
|---|
| 92 |  | 
|---|
| 93 | APIRET  rc; | 
|---|
| 94 |  | 
|---|
| 95 | #ifdef DEBUG | 
|---|
| 96 | /* !paranoia! | 
|---|
| 97 | * Check that the passed in parameters are valid. | 
|---|
| 98 | * If they aren't we'll log this situation and forward the call to ldrOpenPath. | 
|---|
| 99 | */ | 
|---|
| 100 | if ((unsigned)pachFilename < 0x10000 | 
|---|
| 101 | || (unsigned)plv < 0x10000 | 
|---|
| 102 | || cchFilename == 0 | 
|---|
| 103 | || cchFilename >= CCHMAXPATH) | 
|---|
| 104 | { | 
|---|
| 105 | kprintf(("myldrOpenPath: Invalid parameters!!!!\n" | 
|---|
| 106 | "    pachFilename 0x%08x  cchFilename 0x%04x  plv 0x%08x  pful=0x%08x\n", | 
|---|
| 107 | pachFilename, cchFilename, plv, pful | 
|---|
| 108 | )); | 
|---|
| 109 | return ldrOpenPath(pachFilename, cchFilename, plv, pful, lLibPath); | 
|---|
| 110 | } | 
|---|
| 111 | #endif | 
|---|
| 112 |  | 
|---|
| 113 |  | 
|---|
| 114 | /* | 
|---|
| 115 | * We'll check what type of image being opned and save that piece of | 
|---|
| 116 | * information for use in (my)ldrOpen. | 
|---|
| 117 | */ | 
|---|
| 118 | if (plv->lv_type == LVTYPE_EXE) | 
|---|
| 119 | setLdrStateLoadingEXE(); | 
|---|
| 120 | else if (plv->lv_type == LVTYPE_DLL) | 
|---|
| 121 | setLdrStateLoadingDLL(); | 
|---|
| 122 | else | 
|---|
| 123 | setLdrStateLoadingUnsupported(); | 
|---|
| 124 |  | 
|---|
| 125 |  | 
|---|
| 126 | /* | 
|---|
| 127 | * Check if we're to apply the extention fix in myldrOpen. | 
|---|
| 128 | * The required conditions are: | 
|---|
| 129 | *      1. Global class. (ie. DLL) | 
|---|
| 130 | *      2. Name must include a dot. | 
|---|
| 131 | *      3. The extention must not be .DLL. | 
|---|
| 132 | */ | 
|---|
| 133 | fldrOpenExtentionFix =      isDllFixesEnabled() | 
|---|
| 134 | &&  plv->lv_class == CLASS_GLOBAL | 
|---|
| 135 | &&  memchr(pachFilename, '.', cchFilename) | 
|---|
| 136 | &&  (   cchFilename < 4 | 
|---|
| 137 | || memcmp(pachFilename + cchFilename - 4, ".DLL", 4)); | 
|---|
| 138 |  | 
|---|
| 139 | /* | 
|---|
| 140 | * Overload the behaviour of ldrOpenPath? | 
|---|
| 141 | *  - Currently only for DLL loading into the GLOBAL class | 
|---|
| 142 | */ | 
|---|
| 143 | if (isLdrStateLoadingDLL() | 
|---|
| 144 | && (plv->lv_class == CLASS_GLOBAL || plv->lv_class == CLASS_ALL)) | 
|---|
| 145 | { | 
|---|
| 146 | /* | 
|---|
| 147 | * If the executable being loaded is one of our executables we'll | 
|---|
| 148 | * use our method for finding dynamic link libraries. | 
|---|
| 149 | * | 
|---|
| 150 | * At tkExecPgm time this is quite easy. The executable must have been | 
|---|
| 151 | * opened allready and the OUREXE flag will be set if it's one of our | 
|---|
| 152 | * executables. | 
|---|
| 153 | * | 
|---|
| 154 | * At non-tkExecPgm time it's a bit more difficult. We'll have to get | 
|---|
| 155 | * the local infosegment for the process/thread running and check | 
|---|
| 156 | * if the executable (EXE) hMTE is one of ours. We'll do a lookup in | 
|---|
| 157 | * the AVL tree. | 
|---|
| 158 | * | 
|---|
| 159 | * In both cases the result will have to be a module pointer which we | 
|---|
| 160 | * will invoke the overriding ldrOpenPath by. | 
|---|
| 161 | */ | 
|---|
| 162 | PMODULE     pExe = NULL;        /* Pointer to executable which we're to invoke ldrOpenPath by. */ | 
|---|
| 163 | if (isLdrStateExecPgm()) | 
|---|
| 164 | { | 
|---|
| 165 | if (isLdrStateLoadingOurEXE()) | 
|---|
| 166 | pExe = pExeModule; | 
|---|
| 167 | } | 
|---|
| 168 | else | 
|---|
| 169 | { | 
|---|
| 170 | PPTDA   pPTDA = ptdaGetCur(); | 
|---|
| 171 | if (pPTDA) | 
|---|
| 172 | { | 
|---|
| 173 | pExe = getModuleByhMTE(ptdaGet_ptda_module(pPTDA)); | 
|---|
| 174 | #ifdef DEBUG            /* While testing! */ | 
|---|
| 175 | kprintf(("myldrOpenPath: getModuleByhMTE returned 0x%08x for hmod=0x%04x\n", | 
|---|
| 176 | pExe, ptdaGet_ptda_module(pPTDA))); | 
|---|
| 177 | #endif | 
|---|
| 178 | } | 
|---|
| 179 | } | 
|---|
| 180 |  | 
|---|
| 181 | /* | 
|---|
| 182 | * If executable module was found the invoke the overriding ldrOpenPath function. | 
|---|
| 183 | */ | 
|---|
| 184 | if (pExe != NULL) | 
|---|
| 185 | { | 
|---|
| 186 | /* We'll have to save the TCBFailErr since we don't want to cause | 
|---|
| 187 | * Hard Errors while searching invalid paths, etc. (ldrOpenPath does this!) | 
|---|
| 188 | */ | 
|---|
| 189 | USHORT  TCBFailErr_save = tcbGetTCBFailErr(tcbGetCur()); | 
|---|
| 190 | rc = pExe->Data.pModule->openPath(pachFilename, cchFilename, plv, pful, lLibPath); | 
|---|
| 191 | tcbSetTCBFailErr(tcbGetCur(), TCBFailErr_save); | 
|---|
| 192 | } | 
|---|
| 193 | else | 
|---|
| 194 | rc = ldrOpenPath(pachFilename, cchFilename, plv, pful, lLibPath); | 
|---|
| 195 | } | 
|---|
| 196 | else | 
|---|
| 197 | rc = ldrOpenPath(pachFilename, cchFilename, plv, pful, lLibPath); | 
|---|
| 198 |  | 
|---|
| 199 |  | 
|---|
| 200 | /* | 
|---|
| 201 | * Change Loader State - Clear the type part of the loading bits. | 
|---|
| 202 | */ | 
|---|
| 203 | setLdrStateClearLoadingType(); | 
|---|
| 204 |  | 
|---|
| 205 | /* | 
|---|
| 206 | * Clear the extention fix flag. | 
|---|
| 207 | */ | 
|---|
| 208 | fldrOpenExtentionFix = FALSE; | 
|---|
| 209 |  | 
|---|
| 210 | return rc; | 
|---|
| 211 | } | 
|---|
| 212 |  | 
|---|
| 213 |  | 
|---|
| 214 |  | 
|---|
| 215 | /** | 
|---|
| 216 | * Wrapper for the old (pre 14053) versions. | 
|---|
| 217 | * the new parameter is set to 3. | 
|---|
| 218 | */ | 
|---|
| 219 | ULONG LDRCALL myldrOpenPath_old( /* retd  0x10 */ | 
|---|
| 220 | PCHAR       pachFilename,    /* ebp + 0x08 */ | 
|---|
| 221 | USHORT      cchFilename,     /* ebp + 0x0c */ | 
|---|
| 222 | ldrlv_t *   plv,             /* ebp + 0x10 */ | 
|---|
| 223 | PULONG      pful             /* ebp + 0x14 */ | 
|---|
| 224 | ) | 
|---|
| 225 | { | 
|---|
| 226 | return myldrOpenPath(pachFilename, cchFilename, plv, pful, 3); | 
|---|
| 227 | } | 
|---|
| 228 |  | 
|---|
| 229 |  | 
|---|