[6192] | 1 | /* $Id: myldrFindModule.cpp,v 1.3 2001-07-07 04:39:11 bird Exp $
|
---|
[4779] | 2 | *
|
---|
| 3 | * ldrFindModule - ldrFindModule replacement with support for long DLL names
|
---|
| 4 | * and .DLL-extention dependency.
|
---|
| 5 | *
|
---|
| 6 | * Copyright (c) 1999-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
|
---|
[5086] | 17 | #define INCL_OS2KRNL_LDR
|
---|
[4779] | 18 |
|
---|
| 19 | /*******************************************************************************
|
---|
| 20 | * Header Files *
|
---|
| 21 | *******************************************************************************/
|
---|
| 22 | #include <os2.h>
|
---|
| 23 |
|
---|
| 24 | #include <memory.h>
|
---|
| 25 | #include <stdlib.h>
|
---|
| 26 | #include <string.h>
|
---|
| 27 |
|
---|
| 28 | #include "devSegDf.h" /* Win32k segment definitions. */
|
---|
| 29 | #include "log.h"
|
---|
| 30 | #include "avl.h"
|
---|
| 31 | #include <peexe.h>
|
---|
| 32 | #include <exe386.h>
|
---|
| 33 | #include "OS2Krnl.h"
|
---|
| 34 | #include "dev32.h"
|
---|
| 35 | #include "ldr.h"
|
---|
| 36 | #include "ModuleBase.h"
|
---|
| 37 | #include "options.h"
|
---|
| 38 |
|
---|
| 39 | /*******************************************************************************
|
---|
| 40 | * Global Variables *
|
---|
| 41 | *******************************************************************************/
|
---|
| 42 | extern PPMTE pmte_h;
|
---|
| 43 | extern PPMTE pprogram_h;
|
---|
| 44 | extern PPMTE pprogram_l;
|
---|
| 45 | extern PPMTE pglobal_h;
|
---|
| 46 | extern PPMTE pglobal_l;
|
---|
| 47 | extern PPMTE pspecific_h;
|
---|
| 48 | extern PPMTE pspecific_l;
|
---|
| 49 |
|
---|
[6192] | 50 | /*******************************************************************************
|
---|
| 51 | * Internal Functions *
|
---|
| 52 | *******************************************************************************/
|
---|
| 53 | int mymemicmp(void *pv1, void *pv2, unsigned int cch);
|
---|
[4779] | 54 |
|
---|
[6192] | 55 |
|
---|
[4779] | 56 | /**
|
---|
| 57 | * Finds a module if it's loaded.
|
---|
| 58 | *
|
---|
| 59 | * This replacement will support DLLs with non DLL extention
|
---|
| 60 | * and names longer than 8 chars.
|
---|
| 61 | *
|
---|
| 62 | * @returns NO_ERROR on success.
|
---|
[6192] | 63 | * If not found we'll still return NO_ERROR, but *ppMTE is NULL.
|
---|
[4779] | 64 | * OS/2 errorcode on error.
|
---|
| 65 | * @param pachFilename Pointer to module filename.
|
---|
| 66 | * If usClass isn't CLASS_GLOBAL then the string
|
---|
| 67 | * will have to be null terminated or in ldrpFileNameBuf.
|
---|
| 68 | * If it's in the ldrpFileNameBuf we assume a fullly qualified name.
|
---|
| 69 | * @param cchFilename Length of modulefilename. This should including the terminator
|
---|
| 70 | * character if usClass isn't CLASS_GLOBAL.
|
---|
| 71 | * @param usClass Module class. (CLASS_*)
|
---|
| 72 | * @param ppMTE Pointer to pMTE found.
|
---|
| 73 | * @sketch
|
---|
| 74 | * Check that parameters are supported - backout to original ldrFindModule.
|
---|
| 75 | * Check for empty name.
|
---|
| 76 | * Decide upon where to start search for the module - depends on usClass.
|
---|
| 77 | * *TODO*
|
---|
| 78 | */
|
---|
| 79 | ULONG LDRCALL myldrFindModule(PCHAR pachFilename, USHORT cchFilename, USHORT usClass, PPMTE ppMTE)
|
---|
| 80 | {
|
---|
[6192] | 81 | /*
|
---|
| 82 | * Log.
|
---|
| 83 | */
|
---|
| 84 | kprintf(("myldrFindModule: fn=%.*s len=%d class=0x%02x ppMTE=0x%08x\n", cchFilename, pachFilename, cchFilename, usClass, ppMTE));
|
---|
| 85 |
|
---|
[4779] | 86 | /* Check if this feature is enabled */
|
---|
| 87 | if (isDllFixesDisabled())
|
---|
| 88 | {
|
---|
| 89 | #ifdef DEBUG
|
---|
| 90 | APIRET rc = ldrFindModule(pachFilename, cchFilename, usClass, ppMTE);
|
---|
[6192] | 91 | if (rc == NO_ERROR && *ppMTE == NULL)
|
---|
| 92 | kprintf(("myldrFindModule: Not Found\n"));
|
---|
| 93 | else
|
---|
| 94 | kprintf((usClass == CLASS_GLOBAL
|
---|
| 95 | ? "myldrFindModule: Found pmte=0x%08x hmte=0x%04x modname=%.8s path=%s (GLOBAL)\n"
|
---|
| 96 | : "myldrFindModule: Found pmte=0x%08x hmte=0x%04x modname=%.8s path=%s (%x)\n",
|
---|
| 97 | *ppMTE, (*ppMTE)->mte_handle, (*ppMTE)->mte_modname,
|
---|
| 98 | (*ppMTE)->mte_swapmte->smte_path, (*ppMTE)->mte_flags1 & CLASS_MASK));
|
---|
[4779] | 99 | return rc;
|
---|
| 100 | #else
|
---|
| 101 | return ldrFindModule(pachFilename, cchFilename, usClass, ppMTE);
|
---|
| 102 | #endif
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | /* Static variables */
|
---|
| 106 | static PMTE pmteNULL = NULL;
|
---|
| 107 | static PPMTE ppmteNULL = &pmteNULL;
|
---|
| 108 | static PPMTE * apppmteHeadTail[] =
|
---|
| 109 | {/* head tail */
|
---|
| 110 | &pmte_h, &ppmteNULL, /* CLASS_ALL 0x00000000 */
|
---|
| 111 | &pprogram_h, &pprogram_l, /* CLASS_PROGRAM 0x00000040 */
|
---|
| 112 | &pglobal_h, &pglobal_l, /* CLASS_GLOBAL 0x00000080 */
|
---|
| 113 | &pspecific_h, &pspecific_l, /* CLASS_SPECIFIC 0x000000c0 */
|
---|
| 114 | };
|
---|
| 115 |
|
---|
| 116 | /* Local variables */
|
---|
| 117 | PMTE pmte; /* Current MTE. */
|
---|
| 118 | PMTE pmteEnd; /* The MTE top stop at. */
|
---|
| 119 | ULONG rc; /* Return code. */
|
---|
| 120 | PCHAR pachName; /* Pointer to the name part of pachFilename. */
|
---|
| 121 | int cchName; /* Length of the name part of pachFilename. (No extention.) */
|
---|
| 122 | PCHAR pachExt; /* Pointer to the extention part of pachFilename. (not dot!) */
|
---|
| 123 | int cchExt; /* Length of the extention part of pachFilename. (not dot!) */
|
---|
| 124 | int cchName8; /* Length of modname in MTE. */
|
---|
[6192] | 125 | int fDllExt = FALSE; /* Set if we have a .DLL extention. */
|
---|
[4779] | 126 |
|
---|
| 127 | /*
|
---|
| 128 | * Check if everything is the way it used to be... (unsupported kernel changes, etc.)
|
---|
| 129 | */
|
---|
| 130 | #ifdef DEBUG
|
---|
| 131 | if (usClass & ~(CLASS_ALL | CLASS_PROGRAM | CLASS_GLOBAL | CLASS_SPECIFIC | SEARCH_FULL_NAME))
|
---|
| 132 | {
|
---|
| 133 | kprintf(("myldrFindModule: Unknown class flag! usClass=%d\n", usClass));
|
---|
| 134 | return ldrFindModule(pachFilename, cchFilename, usClass, ppMTE);
|
---|
| 135 | }
|
---|
| 136 | #endif
|
---|
| 137 |
|
---|
| 138 | if (pachFilename < (PCHAR)0x10000 || ppMTE < (PPMTE)0x10000)
|
---|
| 139 | {
|
---|
| 140 | kprintf(("myldrFindModule: Invalid pointer(s); pachFilename=0x%08x ppMTE=0x%08x", pachFilename, ppMTE));
|
---|
| 141 | return ERROR_INVALID_ACCESS;
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 |
|
---|
| 145 | /*
|
---|
| 146 | * Can't find an empty name.
|
---|
| 147 | */
|
---|
| 148 | if (cchFilename == 0)
|
---|
| 149 | {
|
---|
| 150 | *ppMTE = NULL;
|
---|
| 151 | kprintf(("myldrFindModule: Not found; cchFilename = 0\n"));
|
---|
| 152 | return ERROR_FILE_NOT_FOUND;
|
---|
| 153 | }
|
---|
| 154 |
|
---|
| 155 |
|
---|
| 156 | /*
|
---|
| 157 | * Find start and end mte node
|
---|
| 158 | */
|
---|
| 159 | pmte = **apppmteHeadTail[usClass >> 5];
|
---|
| 160 | pmteEnd = **apppmteHeadTail[(usClass >> 5) + 1];
|
---|
| 161 | if (pmteEnd != NULL) /* Advance one node - see loop condition. */
|
---|
| 162 | pmteEnd = pmteEnd->mte_link;
|
---|
| 163 |
|
---|
| 164 |
|
---|
| 165 | /*
|
---|
| 166 | * Translate filename path if we're searching for a full name.
|
---|
| 167 | */
|
---|
| 168 | if (usClass != CLASS_GLOBAL)
|
---|
| 169 | {
|
---|
| 170 | if (pachFilename != ldrpFileNameBuf)
|
---|
| 171 | {
|
---|
| 172 | rc = ldrTransPath(pachFilename);
|
---|
| 173 | if (rc)
|
---|
| 174 | return rc;
|
---|
| 175 | pachFilename = ldrpFileNameBuf;
|
---|
| 176 | cchFilename = (USHORT)(strlen(pachFilename) + 1);
|
---|
| 177 | ldrUCaseString(pachFilename, cchFilename);
|
---|
| 178 | }
|
---|
| 179 | #ifdef DEBUG
|
---|
| 180 | else
|
---|
| 181 | {
|
---|
| 182 | if (cchFilename != strlen(pachFilename) + 1)
|
---|
| 183 | kprintf(("myldrFindModule: %.*s cchFilename=%d strlen+1=%d\n",
|
---|
| 184 | cchFilename, pachFilename, cchFilename, strlen(pachFilename) + 1));
|
---|
| 185 | cchFilename = (USHORT)(strlen(pachFilename) + 1);
|
---|
| 186 | }
|
---|
| 187 | #endif
|
---|
| 188 | }
|
---|
| 189 |
|
---|
| 190 |
|
---|
| 191 | /*
|
---|
| 192 | * Depending on the search type we'll have to find the name and
|
---|
| 193 | * extention of the filename passed in to us.
|
---|
| 194 | */
|
---|
| 195 | if (usClass == CLASS_GLOBAL)
|
---|
| 196 | { /*
|
---|
| 197 | * Dll, assumes modulename only (no path!).
|
---|
| 198 | * Find the extention.
|
---|
| 199 | * Determin name and extention length.
|
---|
| 200 | * (NB! Can't use ldrGetFileName since it's looking for a slash.)
|
---|
| 201 | */
|
---|
| 202 | pachName = pachFilename;
|
---|
| 203 | pachExt = pachFilename + cchFilename - 1;
|
---|
| 204 | while (pachExt >= pachName && *pachExt != '.')
|
---|
| 205 | pachExt--;
|
---|
| 206 | if (pachExt < pachFilename)
|
---|
| 207 | {
|
---|
| 208 | cchName = cchFilename;
|
---|
| 209 | pachExt = "DLL";
|
---|
| 210 | cchExt = 3;
|
---|
[6192] | 211 | fDllExt = TRUE;
|
---|
[4779] | 212 | }
|
---|
| 213 | else
|
---|
| 214 | {
|
---|
| 215 | cchName = pachExt - pachName;
|
---|
[6192] | 216 | cchExt = cchFilename - cchName - 1;
|
---|
| 217 | if ( cchExt == 3 && !memcmp(pachExt, ".DLL", 4)
|
---|
| 218 | || cchName < 8 && !memcmp(pachExt, ".DLL", min(3, cchExt))
|
---|
| 219 | )
|
---|
| 220 | fDllExt = TRUE;
|
---|
[4779] | 221 | pachExt++;
|
---|
| 222 | }
|
---|
| 223 |
|
---|
[6192] | 224 | if (fDllExt)
|
---|
| 225 | cchName8 = cchName > 8 ? 8 : cchName;
|
---|
| 226 | else
|
---|
| 227 | cchName8 = cchFilename > 8 ? 8 : cchFilename;
|
---|
[4779] | 228 |
|
---|
| 229 | #ifdef DEBUG
|
---|
| 230 | if ( memchr(pachFilename, '\\', cchFilename)
|
---|
| 231 | || memchr(pachFilename, '/', cchFilename)
|
---|
| 232 | || (cchFilename > 2 && pachFilename[1] == ':')
|
---|
| 233 | )
|
---|
| 234 | {
|
---|
| 235 | kprintf(("myldrFindModule: Invalid name in class global; name=%.*s\n", cchFilename, pachFilename));
|
---|
| 236 | return ERROR_INVALID_NAME;
|
---|
| 237 | }
|
---|
| 238 | #endif
|
---|
| 239 | } else if ( (usClass & ~SEARCH_FULL_NAME) == CLASS_SPECIFIC
|
---|
| 240 | || usClass & CLASS_GLOBAL
|
---|
| 241 | )
|
---|
| 242 | { /*
|
---|
| 243 | * Find name and extention, and the length of those.
|
---|
| 244 | */
|
---|
| 245 | cchName = (int)ldrGetFileName2(pachFilename, (PCHAR*)SSToDS(&pachName), (PCHAR*)SSToDS(&pachExt));
|
---|
| 246 | cchName8 = cchName > 8 ? 8 : cchName;
|
---|
| 247 | cchExt = (pachExt) ? strlen(pachExt) : 0;
|
---|
| 248 | #ifdef DEBUG
|
---|
| 249 | if (cchName <= 0)
|
---|
| 250 | {
|
---|
| 251 | kprintf(("myldrFindModule: Invalid name! ldrGetFileName2 failed; name=%.*s\n", cchFilename, pachFilename));
|
---|
| 252 | return ERROR_INVALID_NAME;
|
---|
| 253 | }
|
---|
| 254 | #endif
|
---|
| 255 | }
|
---|
| 256 | else
|
---|
| 257 | { /*
|
---|
| 258 | * Search the whole path no need for extention or name.
|
---|
| 259 | */
|
---|
| 260 | cchName8 = cchExt = cchName = 0;
|
---|
| 261 | pachName = pachExt = NULL;
|
---|
| 262 | }
|
---|
| 263 |
|
---|
| 264 |
|
---|
| 265 | /*
|
---|
| 266 | * Search loop.
|
---|
| 267 | */
|
---|
| 268 | for (pmte = pmte; pmte != pmteEnd; pmte = pmte->mte_link)
|
---|
| 269 | {
|
---|
| 270 | /*
|
---|
| 271 | * Check that we're still searching within mte of the correct class.
|
---|
| 272 | * (Isn't this a debug sanity check? It's present in release kernel too!
|
---|
| 273 | * If this test is true the MTE list is corrupted!)
|
---|
| 274 | */
|
---|
| 275 | if ( (usClass & CLASS_MASK) != CLASS_ALL
|
---|
| 276 | && (pmte->mte_flags1 & CLASS_MASK) != (usClass & CLASS_MASK))
|
---|
| 277 | {
|
---|
| 278 | kprintf(("myldrFindModule: Bad MTE list? Stopped on wrong class test. pmte=0x%08x usClass=0x%04x\n",
|
---|
| 279 | pmte, usClass));
|
---|
| 280 | break;
|
---|
| 281 | }
|
---|
| 282 |
|
---|
| 283 |
|
---|
| 284 | /*
|
---|
| 285 | * Look if this module matches. Lookup on global (DLL) modules
|
---|
| 286 | * are special case.
|
---|
| 287 | */
|
---|
| 288 | if (usClass == CLASS_GLOBAL)
|
---|
[6192] | 289 | {
|
---|
| 290 | #if 0 /* fault code... Search for DBE.DLL may hit DBEQ.DLL.. */
|
---|
| 291 | /*
|
---|
[4779] | 292 | * DLLs, match name only:
|
---|
| 293 | * Check the module name from the resident MTE.
|
---|
| 294 | * Check the filename part of the fullname in the SwapMTE.
|
---|
| 295 | * Check extention.
|
---|
| 296 | */
|
---|
| 297 | PCHAR pachName2;
|
---|
| 298 | PCHAR pachExt2;
|
---|
| 299 | PSMTE pSMTE = pmte->mte_swapmte;
|
---|
| 300 |
|
---|
| 301 | if ( !memcmp(pmte->mte_modname, pachFilename, cchName8)
|
---|
| 302 | && ( /* Filename < 8 char, check modname only. */
|
---|
| 303 | (cchFilename < 8 && pmte->mte_modname[cchFilename] == '\0')
|
---|
| 304 | || /* Filename >= 8 chars, we'll have to check the fullname. */
|
---|
| 305 | ( ldrGetFileName2(pSMTE->smte_path, (PCHAR*)SSToDS(&pachName2), (PCHAR*)SSToDS(&pachExt2)) == cchName
|
---|
| 306 | && !memcmp(pachName2, pachName, cchName)
|
---|
| 307 | && (cchExt == 0
|
---|
| 308 | ? pachExt2 == NULL || *pachExt2 == '\0' /* If no extention the internal name contains a '.'. The filename may also contain a dot or it should not have an extention! This works for both cases. */
|
---|
| 309 | : cchExt == pSMTE->smte_path - pachExt2 + /* This works when pachExt2 is NULL too. */
|
---|
| 310 | (pSMTE->smte_pathlen /* DOSCALLS don't have smte_pathlen set correctly */
|
---|
| 311 | ? pSMTE->smte_pathlen
|
---|
| 312 | : strlen(pSMTE->smte_path)
|
---|
| 313 | )
|
---|
| 314 | && !memcmp(pachExt2, pachExt, cchExt)
|
---|
| 315 | )
|
---|
| 316 | )
|
---|
| 317 | )
|
---|
| 318 | )
|
---|
[6192] | 319 | #else
|
---|
| 320 | BOOL fFound; /* Flag which is set if this mte match the name we're searching for. */
|
---|
| 321 |
|
---|
| 322 | if (cchName <= 8 && fDllExt)
|
---|
| 323 | { /*
|
---|
| 324 | * Compatability code.
|
---|
| 325 | * Well only near compatible. If the internalname contains .DLL we will be able
|
---|
| 326 | * to find a few modules which OS2 normally won't find. Disable the latest check
|
---|
| 327 | * to make us 100% compatible.
|
---|
| 328 | */
|
---|
| 329 | fFound = !memcmp(pmte->mte_modname, pachFilename, cchName)
|
---|
| 330 | && ( cchName == 8
|
---|
| 331 | || pmte->mte_modname[cchName] == '\0'
|
---|
| 332 | || !memcmp(&pmte->mte_modname[cchName], ".DLL", min(5, 8 - cchName)) /* extra feature */
|
---|
| 333 | );
|
---|
| 334 | }
|
---|
| 335 | else
|
---|
| 336 | { /*
|
---|
| 337 | * Extention code.
|
---|
| 338 | * There is a part of the name in the mte_modname. Check that first to eliminate
|
---|
| 339 | * the next step where we access swappable code.
|
---|
| 340 | * fDllExt:
|
---|
| 341 | * These may or may not include the .DLL extention in the internal name.
|
---|
| 342 | * !fDllExt:
|
---|
| 343 | * These should contain the entire name in the internal name.
|
---|
| 344 | * If no filename extension, then the internal name should end with a '.'.
|
---|
| 345 | * NB! We have an issue of casesensitivity here... (ARG!!!)
|
---|
| 346 | * That make this stuff a bit more expensive...
|
---|
| 347 | * Possible fix is to use the filename, or to require an uppercased internal name...
|
---|
| 348 | */
|
---|
| 349 | fFound = !memcmp(pmte->mte_modname, pachFilename, cchName8);
|
---|
| 350 | if (fFound)
|
---|
| 351 | {
|
---|
| 352 | PCHAR pachResName; /* Pointer to the internal name - resname.0 */
|
---|
| 353 | pachResName = (PCHAR)pmte->mte_swapmte->smte_restab;
|
---|
| 354 | if ((char*)pachResName < (char*)0x10000)
|
---|
| 355 | {
|
---|
| 356 | kprintf(("myldrFindModule: Holy Hand Grenade! there aint any resident names for this mte (0x%x)\n", pmte));
|
---|
| 357 | pachResName = "\0";
|
---|
| 358 | }
|
---|
| 359 | if (fDllExt)
|
---|
| 360 | fFound = ( *pachResName == cchName
|
---|
| 361 | || ( *pachResName == cchName + 4
|
---|
| 362 | && !mymemicmp(&pachResName[1+cchName], ".DLL", 4)
|
---|
| 363 | )
|
---|
| 364 | )
|
---|
| 365 | && !mymemicmp(pachResName + 1, pachFilename, cchName);
|
---|
| 366 | else
|
---|
| 367 | fFound = *pachResName == cchName + cchExt + 1
|
---|
| 368 | && !mymemicmp(pachResName+1, pachFilename, cchName + cchExt + 1);
|
---|
| 369 | }
|
---|
| 370 | }
|
---|
| 371 |
|
---|
| 372 | if (fFound)
|
---|
| 373 | #endif
|
---|
[4779] | 374 | {
|
---|
| 375 | *ppMTE = pmte;
|
---|
| 376 | kprintf(("myldrFindModule: Found pmte=0x%08x hmte=0x%04x modname=%.8s path=%s (GLOBAL)\n",
|
---|
[6192] | 377 | pmte, pmte->mte_handle, pmte->mte_modname, pmte->mte_swapmte->smte_path));
|
---|
[4779] | 378 | return NO_ERROR;
|
---|
| 379 | }
|
---|
| 380 | }
|
---|
| 381 | else
|
---|
| 382 | { /*
|
---|
| 383 | * All, match full name:
|
---|
| 384 | * Check the module name before checking the
|
---|
| 385 | * fullname in the SwapMTE.
|
---|
| 386 | */
|
---|
| 387 | PSMTE pSMTE = pmte->mte_swapmte;
|
---|
[6192] | 388 | if ( ( cchName8 == 0 /* This is 0 if we should not check the mte_modname. */
|
---|
| 389 | || !memcmp(pmte->mte_modname, pachName, cchName8)
|
---|
| 390 | )
|
---|
[4779] | 391 | && pSMTE->smte_pathlen == cchFilename - 1
|
---|
| 392 | && !memcmp(pSMTE->smte_path, pachFilename, cchFilename) /* checks the '\0' too. */
|
---|
| 393 | )
|
---|
| 394 | {
|
---|
| 395 | *ppMTE = pmte;
|
---|
| 396 | kprintf(("myldrFindModule: Found pmte=0x%08x hmte=0x%04x modname=%.8s path=%s (%x)\n",
|
---|
| 397 | pmte, pmte->mte_handle, pmte->mte_modname, pSMTE->smte_path, pmte->mte_flags1 & CLASS_MASK));
|
---|
| 398 | return NO_ERROR;
|
---|
| 399 | }
|
---|
| 400 | }
|
---|
| 401 | } /* Search loop */
|
---|
| 402 |
|
---|
| 403 |
|
---|
| 404 | /*
|
---|
| 405 | * Not found. (*ppMte indicates this).
|
---|
| 406 | */
|
---|
| 407 | *ppMTE = NULL;
|
---|
| 408 | kprintf(("myldrFindModule: Not Found\n"));
|
---|
| 409 | return NO_ERROR;
|
---|
| 410 | }
|
---|
| 411 |
|
---|
[6192] | 412 |
|
---|
| 413 |
|
---|
| 414 | /**
|
---|
| 415 | * This function is needed since pv1 might be a mixed case name.
|
---|
| 416 | * @returns same as memcmp.
|
---|
| 417 | * @param pv1 Pointer to resident name or part of that. Might be mixed cased.
|
---|
| 418 | This is uppercased.
|
---|
| 419 | * @param pv2 Pointer to name. ASSUMES Uppercase.
|
---|
| 420 | * @param cch Length
|
---|
| 421 | * @remark
|
---|
| 422 | */
|
---|
| 423 | int mymemicmp(void *pv1, void *pv2, unsigned int cch)
|
---|
| 424 | {
|
---|
| 425 | #if 0 /* safe code which doesn't modify the resident name... */
|
---|
| 426 | if (!memcmp(pv1, pv2, cch))
|
---|
| 427 | return 0;
|
---|
| 428 | char *pach = (char*)SSToDS(alloca(cch));
|
---|
| 429 | memcpy(pach, pv2, cch);
|
---|
| 430 | ldrUCaseString(pach, cch);
|
---|
| 431 | return memcmp(pv1, pach, cch);
|
---|
| 432 | #else
|
---|
| 433 | if (!memcmp(pv1, pv2, cch))
|
---|
| 434 | return 0;
|
---|
| 435 | ldrUCaseString((PCHAR)pv1, cch);
|
---|
| 436 | return memcmp(pv1, pv2, cch);
|
---|
| 437 | #endif
|
---|
| 438 | }
|
---|