Ignore:
Timestamp:
Aug 25, 2000, 6:47:28 AM (25 years ago)
Author:
bird
Message:

Coding more or less completed.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/GRACE/src/win32k/pe2lx/pe2lx.cpp

    r4076 r4090  
    1 /* $Id: pe2lx.cpp,v 1.18.4.7 2000-08-24 01:36:26 bird Exp $
     1/* $Id: pe2lx.cpp,v 1.18.4.8 2000-08-25 04:47:26 bird Exp $
    22 *
    33 * Pe2Lx class implementation. Ring 0 and Ring 3
     
    9595#ifdef RING0
    9696    #include "ldrCalls.h"               /* ldr* calls. (ldrRead) */
     97    #include "avl.h"                    /* AVL tree. (ldr.h need it) */
     98    #include "ldr.h"                    /* ldr helpers. (ldrGetExePath) */
     99    #include "env.h"                    /* Environment helpers. */
    97100#endif
    98101#include "modulebase.h"                 /* ModuleBase class definitions, ++. */
     
    173176LONG            Pe2Lx::cLoadedModules;  /* Count of existing objects. Updated by constructor and destructor. */
    174177const char *    Pe2Lx::pszOdin32Path;   /* Odin32 base path (include a slash). */
     178ULONG           Pe2Lx::cchOdin32Path;   /* Odin32 base path length. */
    175179SFN             Pe2Lx::sfnKernel32;     /* Odin32 Kernel32 filehandle. */
    176180
     
    13081312 * @returns   OS2 return code.
    13091313 *            pLdrLv->lv_sfn  is set to filename handle.
    1310  * @param     pachModname   Pointer to modulename. Not zero terminated!
    1311  * @param     cchModname    Modulename length.
     1314 * @param     pachFilename  Pointer to filename. Not zero terminated!
     1315 * @param     cchFilename   Filename length.
    13121316 * @param     pLdrLv        Loader local variables? (Struct from KERNEL.SDF)
    1313  * @param     pfl           Pointer to flags which are passed on to ldrOpen.
     1317 * @param     pful          Pointer to flags which are passed on to ldrOpen.
    13141318 * @sketch
    13151319 * This is roughly what the original ldrOpenPath does:
     
    13241328 *      endif
    13251329 */
    1326 ULONG  Pe2Lx::openPath(PCHAR pachModname, USHORT cchModname, ldrlv_t *pLdrLv, PULONG pfl) /* (ldrOpenPath) */
     1330ULONG  Pe2Lx::openPath(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *pLdrLv, PULONG pful) /* (ldrOpenPath) */
    13271331{
    13281332    #ifdef RING0
    1329     #if 1
    1330     initOdin32Path();
    1331     return ldrOpenPath(pachModname, cchModname, pLdrLv, pfl);
     1333
     1334    /*
     1335     * Mark the SFN invalid in the case of error.
     1336     * Initiate the Odin32 Path static variable and call worker.
     1337     */
     1338    return openPath2(pachFilename, cchFilename, pLdrLv, pful, initOdin32Path());
     1339
    13321340    #else
    1333 
     1341    NOREF(pachFilename);
     1342    NOREF(cchFilename);
     1343    NOREF(pLdrLv);
     1344    NOREF(pful);
     1345    return ERROR_NOT_SUPPORTED;
     1346    #endif
     1347}
     1348
     1349
     1350/**
     1351 * openPath2 - Worker for openPath which is also used by initOdin32Path.
     1352 *
     1353 * @returns   OS2 return code.
     1354 *            pLdrLv->lv_sfn  is set to filename handle.
     1355 * @param     pachFilename      Pointer to filename. Not zero terminated!
     1356 * @param     cchFilename       Filename length.
     1357 * @param     pLdrLv            Loader local variables? (Struct from KERNEL.SDF)
     1358 * @param     pful              Pointer to flags which are passed on to ldrOpen.
     1359 * @param     fOdin32PathValid  Flag indicating that the pszOdin32Path is valid or not.
     1360 * @sketch
     1361 * This is roughly what the original ldrOpenPath does:
     1362 *      if !CLASS_GLOBAL or miniifs then
     1363 *          ldrOpen(pachModName)
     1364 *      else
     1365 *          loop until no more libpath elements
     1366 *              get next libpath element and add it to the modname.
     1367 *              try open the modname
     1368 *              if successfull then break the loop.
     1369 *          endloop
     1370 *      endif
     1371 */
     1372ULONG  Pe2Lx::openPath2(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *pLdrLv, PULONG pful, BOOL fOdin32PathValid)
     1373{
     1374    #ifdef RING0
     1375
     1376    APIRET  rc;                         /* Returncode. */
     1377    ULONG   cchExt;                     /* Count of chars in additional extention. (0 if extention exists.) */
    13341378
    13351379    /* These defines sets the order the paths and pathlists are examined. */
     
    13401384    #define FINDDLL_WINDIR          5
    13411385    #define FINDDLL_PATH            6
    1342     #define FINDDLL_BEGINLIBPATH    7
    1343     #define FINDDLL_LIBPATH         8
    1344     #define FINDDLL_ENDLIBPATH      9
     1386    #define FINDDLL_BEGINLIBPATH    7   /* uses ldrOpenPath */
     1387    #define FINDDLL_LIBPATH         8   /* uses ldrOpenPath */
     1388    #define FINDDLL_ENDLIBPATH      9   /* uses ldrOpenPath */
    13451389    #define FINDDLL_FIRST           FINDDLL_EXECUTABLEDIR
    1346     #define FINDDLL_LAST            FINDDLL_ENDLIBPATH
     1390    #define FINDDLL_LAST            FINDDLL_PATH
    13471391
    13481392    struct _LocalVars
    13491393    {
    13501394        char    sz[CCHMAXPATH];
     1395        char    szPath[CCHMAXPATH];
    13511396    } *pVars;
    13521397
    13531398
    1354     /*
     1399    /** @sketch
    13551400     * Mark the SFN invalid in the case of error.
    1356      * Initiate the Odin32 Path static variable.
    13571401     * Allocate memory for local variables.
     1402     * Check for extention.
    13581403     */
    13591404    pLdrLv->lv_sfn = 0xffff;
    1360     initOdin32Path();
    13611405    pVars = (struct _LocalVars*)rmalloc(sizeof(struct _LocalVars));
    13621406    if (pVars == NULL)
    13631407        return ERROR_NOT_ENOUGH_MEMORY;
    13641408
    1365     /* init stuff */
    1366 
    1367 
     1409    cchExt = cchFilename - 1;
     1410    while (cchExt != 0 && pachFilename[cchExt] != '.')
     1411        cchExt--;
     1412    cchExt = cchExt != 0 ? 0 : 4;
    13681413
    13691414
     
    13731418    for (int iPath = FINDDLL_FIRST; iPath <= FINDDLL_LAST; iPath++)
    13741419    {
    1375         APIRET          rc;             /* Returncode from OS/2 APIs. */
    1376         const char  *   pszPath;        /* Pointer to the path being examined. */
     1420        char  * pszPath;                /* Pointer to the path being examined. */
    13771421
    13781422        /** @sketch
     
    13821426        {
    13831427            case FINDDLL_EXECUTABLEDIR:
    1384                 if (pszAltPath)
    1385                     pszPath = strcpy(plv->szPath, pszAltPath);
    1386                 else
    1387                 {
    1388                     /* ASSUMES: getFullPath allways returns a fully qualified
    1389                      *      path, ie. with at least one backslash. and that all
    1390                      *      slashes are backslashes!
    1391                      */
    1392                     if (!WinExe) continue;
    1393                     pszPath = strcpy(plv->szPath, WinExe->getFullPath());
    1394                 }
    1395                 psz = strrchr(plv->szPath, '\\');
    1396                 dassert(psz, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): "
    1397                         "WinExe->getFullPath returned a path not fully qualified: %s",
    1398                         pszFileName, pszFullName, cchFullName, pszPath));
    1399                 if (psz)
    1400                     *psz = '\0';
    1401                 else
     1428                if ((pszPath = ldrGetExePath(pVars->szPath, TRUE)) == NULL)
    14021429                    continue;
    14031430                break;
     
    14081435
    14091436            case FINDDLL_SYSTEM32DIR:
    1410                 pszPath = InternalGetSystemDirectoryA();
     1437                if (!fOdin32PathValid)
     1438                    continue;
     1439                pszPath = pVars->szPath;
     1440                strcpy(pszPath, pszOdin32Path);
     1441                strcpy(pszPath + cchOdin32Path, "System32");
    14111442                break;
    14121443
    14131444            case FINDDLL_SYSTEM16DIR:
    1414                 #if 1
    1415                 continue;               /* Skip this index */
    1416                 #else
    1417                 pszPath = InternalGetWindowsDirectoryA();
    1418                 strcpy(plv->sz2, InternalGetWindowsDirectoryA());
    1419                 strcat(plv->sz2, "\SYSTEM");
     1445                if (!fOdin32PathValid)
     1446                    continue;
     1447                pszPath = pVars->szPath;
     1448                strcpy(pszPath, pszOdin32Path);
     1449                strcpy(pszPath + cchOdin32Path, "System");
    14201450                break;
    1421                 #endif
    14221451
    14231452            case FINDDLL_WINDIR:
    1424                 pszPath = InternalGetWindowsDirectoryA();
     1453                if (!fOdin32PathValid)
     1454                    continue;
     1455                pszPath = pVars->szPath;
     1456                strcpy(pszPath, pszOdin32Path);
     1457                pszPath[cchOdin32Path - 1] = '\0'; /* remove slash */
    14251458                break;
    14261459
    14271460            case FINDDLL_PATH:
    1428                 pszPath = getenv("PATH");
     1461                pszPath = (char*)GetEnv(TRUE);
     1462                if (pszPath == NULL)
     1463                    continue;
     1464                pszPath = (char*)ScanEnv(pszPath, "PATH");
    14291465                break;
    14301466
     1467            #if 0
    14311468            case FINDDLL_BEGINLIBPATH:
    1432                 rc = DosQueryExtLIBPATH(plv->szPath, BEGIN_LIBPATH);
    1433                 if (rc != NO_ERROR)
    1434                 {
    1435                     dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): "
    1436                              "DosQueryExtLIBPATH failed with rc=%d, iPath=%d",
    1437                              pszFileName, pszFullName, cchFullName, rc, iPath));
     1469                pszPath = ptda_GetBeginLibpath()...  ;
     1470                if (pszPath == NULL)
    14381471                    continue;
    1439                 }
    1440                 pszPath = plv->szPath;
    14411472                break;
    14421473
    14431474            case FINDDLL_LIBPATH:
    1444                 rc = DosQueryHeaderInfo(NULLHANDLE, 0, plv->szPath, sizeof(plv->szPath), QHINF_LIBPATH);
    1445                 if (rc != NO_ERROR)
    1446                 {
    1447                     dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): "
    1448                              "DosQueryHeaderInfo failed with rc=%d, iPath=%d",
    1449                              pszFileName, pszFullName, cchFullName, rc, iPath));
     1475                pszPath = *pLdrLibPath;
     1476                break;
     1477
     1478            case FINDDLL_ENDLIBPATH:
     1479                pszPath = ptda_GetEndLibpath()...  ;
     1480                if (pszPath == NULL)
    14501481                    continue;
    1451                 }
    1452                 pszPath = plv->szPath;
    14531482                break;
    1454 
    1455             case FINDDLL_ENDLIBPATH:
    1456                 rc = DosQueryExtLIBPATH(plv->szPath, END_LIBPATH);
    1457                 if (rc != NO_ERROR)
    1458                 {
    1459                     dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): "
    1460                              "DosQueryExtLIBPATH failed with rc=%d, iPath=%d",
    1461                              pszFileName, pszFullName, cchFullName, rc, iPath));
    1462                     continue;
    1463                 }
    1464                 pszPath = plv->szPath;
    1465                 break;
    1466 
     1483            #endif
    14671484            default: /* !internalerror! */
    1468                 goto end;
     1485                printIPE(("Pe2Lx::openPath(%.*s,..): iPath is %d which is invalid.\n", cchFilename, pachFilename, iPath));
     1486                rfree(pVars);
     1487                return ERROR_FILE_NOT_FOUND;
    14691488        }
    14701489
     
    14761495        while (pszPath != NULL && *pszPath != '\0')
    14771496        {
    1478             HDIR    hDir;               /* Find handle used when calling FindFirst. */
    1479             ULONG   culFiles;           /* Number of files to find / found. */
    14801497            char *  pszNext;            /* Pointer to the next pathlist path */
    14811498            int     cch;                /* Length of path (including the slash after the slash is added). */
    14821499
    14831500            /** @sketch
    1484              * Find the end of the path.
    1485              * Copy the path into the plv->sz buffer.
    1486              * Set pszNext.
     1501             * Find the end of the path and set pszNext.
     1502             * Uncount any trailing slash.
     1503             * Check that the filename fits within the buffer (and OS/2 filelength limits).
    14871504             */
    14881505            pszNext = strchr(pszPath, ';');
     
    14951512                cch = strlen(pszPath);
    14961513
    1497             if (cch + cchFileName + 1 >= sizeof(plv->sz)) /* assertion */
     1514            if (pszPath[cch - 1] == '\\' || pszPath[cch-1] == '/')
     1515                cch--;
     1516
     1517            if (cch == 0 || cch + cchFilename + 2 + cchExt > sizeof(pVars->sz)) /* assertion */
    14981518            {
    1499                 dassert(cch + cchFileName + 1 < sizeof(plv->sz), ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): "
    1500                         "cch (%d) + cchFileName (%d) + 1 < sizeof(plv->sz) (%d) - paths too long!, iPath=%d",
    1501                         pszFileName, pszFullName, cchFullName, cch, cchFileName, sizeof(plv->sz), iPath));
     1519                printErr(("Pe2Lx::openPath(%.*s,..): cch (%d) + cchFilename (%d) + 2 + cchExt (%d) > sizeof(pVars->sz) (%d) - path's too long!, iPath=%d",
     1520                          cchFilename, pachFilename, cch, cchExt, cchFilename, sizeof(pVars->sz), iPath));
     1521
    15021522                pszPath = pszNext;
    15031523                continue;
    15041524            }
    1505             memcpy(plv->sz, pszPath, cch); //arg! Someone made strncpy not work as supposed!
    15061525
    15071526
    15081527            /** @sketch
     1528             * Copy the path into the pVars->sz buffer.
    15091529             * Add a '\\' and the filename (pszFullname) to the path;
    15101530             * then we'll have a fullpath.
    15111531             */
    1512             plv->sz[cch++] = '\\';
    1513             strcpy(&plv->sz[cch], pszFullName);
     1532            memcpy(pVars->sz, pszPath, cch);
     1533            pVars->sz[cch++] = '\\';
     1534            memcpy(&pVars->sz[cch], pachFilename, cchFilename);
     1535            if (cchExt != 0)
     1536                memcpy(&pVars->sz[cch + cchFilename], ".DLL", 5);
     1537            else
     1538                pVars->sz[cch + cchFilename] = '\0';
    15141539
    15151540
    15161541            /** @sketch
    1517              *  Use DosFindFirst to check if the file exists.
    1518              *  IF the file exists THEN
    1519              *      Query Fullpath using OS/2 API.
    1520              *      IF unsuccessful THEN return relative name.
    1521              *          Check that the fullname buffer is large enough.
    1522              *          Copy the filename found to the fullname buffer.
    1523              *      ENDIF
    1524              *      IF successful THEN uppercase the fullname buffer.
    1525              *      goto end
    1526              *  ENDIF
     1542             * Try open the file using myLdrOpen.
     1543             * Return if successfully opened or if fatal error.
    15271544             */
    1528             hDir = HDIR_CREATE;
    1529             culFiles = 1;
    1530             rc = DosFindFirst(plv->sz, &hDir, FILE_NORMAL,
    1531                               &plv->findbuf3, sizeof(plv->findbuf3),
    1532                               &culFiles, FIL_STANDARD);
    1533             DosFindClose(hDir);
    1534             if (culFiles >= 1 && rc == NO_ERROR)
     1545            rc = myldrOpen(&pLdrLv->lv_sfn, pVars->sz, pful);
     1546            switch (rc)
    15351547            {
    1536                 /* Return full path - we'll currently return a relative path. */
    1537                 rc = DosQueryPathInfo(plv->sz, FIL_QUERYFULLNAME, pszFullName, cchFullName);
    1538                 fRet = rc == NO_ERROR;
    1539                 if (!fRet)
    1540                 {
    1541                     /* Return a relative path - probably better that failing... */
    1542                     dassert(rc == NO_ERROR, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): "
    1543                             "rc = %d",
    1544                             pszFileName, pszFullName, cchFullName, rc));
    1545 
    1546                     if (cch + cchFileName + 1 <= cchFullName)
    1547                     {
    1548                         strcpy(pszFullName, plv->sz);
    1549                         strcpy(pszFullName + cch, plv->findbuf3.achName);
    1550                         fRet = TRUE;
    1551                     }
    1552                     else
    1553                     {
    1554                         dassert(cch + cchFileName + 1 > cchFullName, ("KERNEL32:Win32ImageBase::findDll(%s, 0x%08x, %d): "
    1555                                 "cch (%d) + cchFileName (%d) + 1 < cchFullName (%d); %s",
    1556                                 pszFileName, pszFullName, cchFullName, cch, cchFileName, cchFullName, plv->sz));
    1557                     }
    1558                 }
    1559                 if (fRet) strupr(pszFullName);
    1560                 goto end;
     1548                /* these errors are ignored */
     1549                case ERROR_FILE_NOT_FOUND:          case ERROR_PATH_NOT_FOUND:          case ERROR_ACCESS_DENIED:           case ERROR_INVALID_ACCESS:
     1550                case ERROR_INVALID_DRIVE:           case ERROR_NOT_DOS_DISK:            case ERROR_REM_NOT_LIST:            case ERROR_BAD_NETPATH:
     1551                case ERROR_NETWORK_BUSY:            case ERROR_DEV_NOT_EXIST:           case ERROR_TOO_MANY_CMDS:           case ERROR_ADAP_HDW_ERR:
     1552                case ERROR_UNEXP_NET_ERR:           case ERROR_BAD_REM_ADAP:            case ERROR_NETNAME_DELETED:         case ERROR_BAD_DEV_TYPE:
     1553                case ERROR_NETWORK_ACCESS_DENIED:   case ERROR_BAD_NET_NAME:            case ERROR_TOO_MANY_SESS:           case ERROR_REQ_NOT_ACCEP:
     1554                case ERROR_INVALID_PASSWORD:        case ERROR_OPEN_FAILED:             case ERROR_INVALID_NAME:            case ERROR_FILENAME_EXCED_RANGE:
     1555                case ERROR_VC_DISCONNECTED:
     1556                    rc = ERROR_FILE_NOT_FOUND;
     1557                    pszPath = pszNext;
     1558                    break;
     1559
     1560                /* all errors and success is let out here */
     1561                case NO_ERROR:
     1562                default:
     1563                    rfree(pVars);
     1564                    return rc;
    15611565            }
    15621566
     1567            /** @sketch
     1568             * Advance to the next path part
     1569             */
    15631570            pszPath = pszNext;
    15641571        }
     
    15661573
    15671574
    1568 end:
    15691575    /*
    15701576     * Cleanup: free local variables.
     1577     * Since we haven't found the file yet we'll return thru ldrOpenPath.
    15711578     */
    1572     free(plv);
    1573     return fRet;
    1574 
    1575 
    1576 
    1577 
    1578 
    1579     return ldrOpenPath(pachModname, cchModname, pLdrLv, pfl);
    1580     #endif
     1579    rfree(pVars);
     1580    return ldrOpenPath(pachFilename, cchFilename, pLdrLv, pful);
     1581
    15811582    #else
    1582     NOREF(pachModname);
    1583     NOREF(cchModname);
     1583    NOREF(pachFilename);
     1584    NOREF(cchFilename);
    15841585    NOREF(pLdrLv);
    1585     NOREF(pfl);
     1586    NOREF(pful);
    15861587    return ERROR_NOT_SUPPORTED;
    15871588    #endif
    15881589}
    1589 
    1590 
    15911590
    15921591
     
    46904689 * Initiates the odin32path.
    46914690 * @returns     Success indicator.
    4692  * @sketch
     4691 * @sketch      If allready inited ok Then do nothing return TRUE.
     4692 *
     4693 *              Check if KERNEL32 is loaded using ldrFindModule.
     4694 *              If loaded then set path according to the smte_path and return.
     4695 *
     4696 *              If the path is set to something then return TRUE. (ie. the following method is allready applied.)
     4697 *
     4698 *              Use odinPath2 to locate the KERNEL32 module in the LIBPATHs. The
     4699 *                win32k loaders are temporarily disabled. Path is returned in
     4700 *                the ldrpFileNameBuf buffer.
     4701 *              If found the Then set path according to ldrpFileNameBuf and return
     4702 *
     4703 *              Fail returning FALSE.
    46934704 * @status
    46944705 * @author      knut st. osmundsen (knut.stange.osmundsen@mynd.no)
     
    47364747     *
    47374748     * For the time being:
    4738      *  We'll use ldrOpenPath to do this, but we'll have to
     4749     *  We'll use odinPath2 to do this, but we'll have to
    47394750     *  disable the win32k.sys overloading temporarily.
    47404751     */
     
    47464757    options.fNoLoader = TRUE;
    47474758    lv.lv_class = CLASS_GLOBAL;
    4748     rc = ldrOpenPath("KERNEL32", 8, (ldrlv_t*)SSToDS(&lv), (PULONG)SSToDS(&ful));
     4759    rc = openPath2("KERNEL32", 8, (ldrlv_t*)SSToDS(&lv), (PULONG)SSToDS(&ful), FALSE);
    47494760    options.fNoLoader = ul;
    47504761    if (rc == NO_ERROR)
     
    47614772    }
    47624773
    4763     return rc == NO_ERROR;
    4764     #else
     4774    #endif
    47654775    return FALSE;
    4766     #endif
    47674776}
    47684777
     
    47804789BOOL Pe2Lx::setOdin32Path(const char *psz)
    47814790{
    4782     const char * pszEnd;
    4783     char * pszPath;
     4791    const char * psz2;
    47844792
    47854793    /*
     
    47874795     * and one directory up. We assume a fully qualified path.
    47884796     */
    4789     pszEnd = psz + strlen(psz) - 1;
    4790     while (pszEnd > psz && *pszEnd != '\\' && *pszEnd != '/' && *pszEnd != ':')
    4791         pszEnd--;
    4792     pszEnd--;
    4793     while (pszEnd > psz && *pszEnd != '\\' && *pszEnd != '/' && *pszEnd != ':')
    4794         pszEnd--;
    4795     if (pszEnd > psz)
    4796     {
     4797    psz2 = psz + strlen(psz) - 1;
     4798    while (psz2 > psz && *psz2 != '\\' && *psz2 != '/' && *psz2 != ':')
     4799        psz2--;
     4800    psz2--;
     4801    while (psz2 > psz && *psz2 != '\\' && *psz2 != '/' && *psz2 != ':')
     4802        psz2--;
     4803    if (psz2 > psz)
     4804    {
     4805        char *pszPath;
    47974806        /*
    47984807         * Free old path (if any) and allocate space for a new path.
     
    48024811        if (pszOdin32Path)
    48034812            rfree((void*)pszOdin32Path);
    4804         if (*pszEnd == ':') //in case someone installed odin in a root directory.
    4805             pszEnd++;
    4806         pszEnd++;       //include the slash
    4807         pszPath = (char*)rmalloc(pszEnd - psz);
     4813        if (*psz2 == ':') //in case someone installed odin in a root directory.
     4814            psz2++;
     4815        psz2++;       //include the slash
     4816        cchOdin32Path = psz2 - psz;
     4817        pszPath = (char*)rmalloc((size_t)cchOdin32Path);
    48084818        if (pszPath == NULL) return FALSE;
    4809         memcpy(pszPath, psz, pszEnd - psz);
    4810         pszPath[pszEnd - psz] = '\0';
     4819        memcpy(pszPath, psz, (size_t)cchOdin32Path);
     4820        pszPath[cchOdin32Path] = '\0';
    48114821        pszOdin32Path = pszPath;
    48124822
Note: See TracChangeset for help on using the changeset viewer.