VirtualBox

Changeset 93138 in vbox for trunk


Ignore:
Timestamp:
Jan 7, 2022 3:06:38 PM (3 years ago)
Author:
vboxsync
Message:

Add/os2: Proper gengradd checks in the installer.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/os2/VBoxOs2AdditionsInstall.cpp

    r93136 r93138  
    125125
    126126
     127/** Writes a variable number of length/strings pairs to @a hFile, stopping at
     128 *  0/NULL. */
     129static void WriteNStrings(HFILE hFile, ...)
     130{
     131    va_list va;
     132    va_start(va, hFile);
     133    for (;;)
     134    {
     135        const char *psz = va_arg(va, const char *);
     136        int         cch = va_arg(va, int);
     137        if (psz)
     138        {
     139            if (cch < 0)
     140                DoWriteStr(hFile, psz);
     141            else
     142                DoWriteNStr(hFile, psz, cch);
     143        }
     144        else
     145            break;
     146    }
     147    va_end(va);
     148}
     149
     150
     151static RTEXITCODE ErrorNStrings(const char *pszMsg, ssize_t cchMsg, ...)
     152{
     153    DoWriteNStr(g_hStdErr, RT_STR_TUPLE("VBoxOs2AdditionsInstall: error: "));
     154    va_list va;
     155    va_start(va, cchMsg);
     156    do
     157    {
     158        if (cchMsg < 0)
     159            DoWriteStr(g_hStdErr, pszMsg);
     160        else
     161            DoWriteNStr(g_hStdErr, pszMsg, cchMsg);
     162        pszMsg = va_arg(va, const char *);
     163        cchMsg = va_arg(va, int);
     164    } while (pszMsg != NULL);
     165    va_end(va);
     166    DoWriteNStr(g_hStdErr, RT_STR_TUPLE("\r\n"));
     167    return RTEXITCODE_FAILURE;
     168}
     169
     170
    127171static char *MyNumToString(char *pszBuf, unsigned uNum)
    128172{
     
    150194    DoWriteStr(hFile, szTmp);
    151195}
     196
    152197
    153198static RTEXITCODE ApiErrorN(APIRET rc, unsigned cMsgs, ...)
     
    462507
    463508
     509/**
     510 * Simplistic case-insensitive memory compare function.
     511 */
     512static int MyMemICmp(void const *pv1, void const *pv2, size_t cb)
     513{
     514    char const *pch1 = (const char *)pv1;
     515    char const *pch2 = (const char *)pv2;
     516    while (cb-- > 0)
     517    {
     518        char ch1 = *pch1++;
     519        char ch2 = *pch2++;
     520        if (   ch1 != ch2
     521            && RT_C_TO_UPPER(ch1) != RT_C_TO_UPPER(ch2))
     522            return (int)ch1 - (int)ch2;
     523    }
     524    return 0;
     525}
     526
     527
    464528/*********************************************************************************************************************************
    465529*   Installation Steps.                                                                                                          *
     
    476540    if (rc != NO_ERROR)
    477541        return ApiErrorN(rc, 3, "DosQueryPathInfo(\"", g_szBootDrivePath, "\",,,) - installed gengradd?");
     542
     543    /* Note! GRADD precense in Config.sys is checked below while modifying it. */
    478544    return RTEXITCODE_SUCCESS;
    479545}
     
    564630
    565631/**
     632 * Strips leading and trailing spaces and commas from the given substring.
     633 *
     634 * This is for GRADD_CHAINS and friends.
     635 */
     636static size_t StripGraddList(const char **ppch, size_t cch)
     637{
     638    const char *pch = *ppch;
     639    while (   cch > 0
     640           && (   RT_C_IS_BLANK(pch[0])
     641               || pch[0] == ',') )
     642        cch--, pch++;
     643    *ppch = pch;
     644
     645    while (   cch > 0
     646           && (   RT_C_IS_BLANK(pch[cch - 1])
     647               || pch[cch - 1] == ',') )
     648        cch--;
     649    return cch;
     650}
     651
     652
     653/**
    566654 * Prepares the config.sys modifications.
    567655 */
     
    636724    bool        fInsertedIfs   = RT_BOOL(g_fSkipMask & SKIP_SHARED_FOLDERS);
    637725    unsigned    cPathsFound    = 0;
     726    const char *pchGraddChains = NULL;
     727    size_t      cchGraddChains = 0;
     728    char        ch0GraddUpper  = 0;
     729    char        ch0GraddLower  = 0;
     730    const char *pchGraddChain1 = NULL;
     731    size_t      cchGraddChain1 = NULL;
    638732    unsigned    iLine  = 0;
    639733    size_t      offSrc = 0;
     
    696790                    }
    697791                    cPathsFound += 1;
     792                }
     793            }
     794            /*
     795             * Look for the GRADD_CHAINS variable.
     796             *
     797             * It is a comma separated list of chains (other env.vars.),
     798             * however we can only deal with a single element.
     799             */
     800            else if (   cchLine - off >= sizeof("GRADD_CHAINS=C") - 1
     801                     && (pchLine[off +  0] == 'G' || pchLine[off + 0] == 'g')
     802                     && (pchLine[off + 12] == '=' || RT_C_IS_BLANK(pchLine[off + 12]))
     803                     && MyMemICmp(&pchLine[off], RT_STR_TUPLE("GRADD_CHAINS")) == 0)
     804            {
     805                off += 12;
     806                SKIP_BLANKS();
     807                if (cchLine > off && pchLine[off] == '=')
     808                {
     809                    off++;
     810                    pchGraddChains = &pchLine[off];
     811                    cchGraddChains = StripGraddList(&pchGraddChains, cchLine - off);
     812
     813                    ch0GraddUpper = RT_C_TO_UPPER(*pchGraddChains);
     814                    ch0GraddLower = RT_C_TO_LOWER(*pchGraddChains);
     815
     816                    pchGraddChain1 = NULL;
     817                    cchGraddChain1 = 0;
     818
     819                    const char *pszComma = (const char *)memchr(pchGraddChains, ',', cchGraddChains);
     820                    if (pszComma)
     821                    {
     822                        cchGraddChains = StripGraddList(&pchGraddChains, pchGraddChains - pszComma);
     823                        WriteStrings(g_hStdOut, "warning: Config.sys line ", MyNumToString(szLineNo, iLine),
     824                                     "GRADD_CHAINS contains more than one element.  Ignoring all but the first.\r\n", NULL);
     825                    }
     826
     827                    if (g_fVerbose)
     828                        WriteNStrings(g_hStdOut, RT_STR_TUPLE("info: Config.sys line "), MyNumToString(szLineNo, iLine), - 1,
     829                                      RT_STR_TUPLE(": SET GRADD_CHAINS="), &pchLine[off], cchLine - off,
     830                                      RT_STR_TUPLE("\r\n"), NULL, 0);
     831                }
     832            }
     833            /*
     834             * Look for the chains listed by GRADD_CHAINS.
     835             *
     836             * We ASSUME this is defined after the GRADD_CHAINS variable since
     837             * this is normally the case.  We'd need to do two passes otherwise,
     838             * and I'm way to lazy to do that now.
     839             */
     840            else if (   (ch0GraddUpper == pchLine[off] || ch0GraddLower == pchLine[off])
     841                     && cchLine - off >= cchGraddChains + 2
     842                     && (pchLine[off + cchGraddChains] == '=' || RT_C_IS_SPACE(pchLine[off + cchGraddChains]))
     843                     && MyMemICmp(&pchLine[off], pchGraddChains, cchGraddChains) == 0)
     844            {
     845                off += cchGraddChains;
     846                SKIP_BLANKS();
     847                if (cchLine > off && pchLine[off] == '=')
     848                {
     849                    off++;
     850                    SKIP_BLANKS();
     851
     852                    /* Just save it, we'll validate it after processing everything. */
     853                    pchGraddChain1 = &pchLine[off];
     854                    cchGraddChain1 = StripGraddList(&pchGraddChain1, cchLine - off);
     855
     856                    if (g_fVerbose)
     857                        WriteNStrings(g_hStdOut, RT_STR_TUPLE("info: Config.sys line "), MyNumToString(szLineNo, iLine), - 1,
     858                                      RT_STR_TUPLE(": Found GRADD chain "), pchGraddChains, cchGraddChains,
     859                                      RT_STR_TUPLE(" with value: "), pchGraddChain1, cchGraddChain1,
     860                                      RT_STR_TUPLE("\r\n"), NULL, 0);
    698861                }
    699862            }
     
    825988    if (!cPathsFound)
    826989        WriteStrings(g_hStdErr, "warning: Found no SET PATH statement in Config.sys.\r\n", NULL);
     990
     991    /*
     992     * If we're installing the graphics driver, check that GENGRADD is in the
     993     * primary GRADD chain.
     994     */
     995    if (!(g_fSkipMask & SKIP_GRAPHICS))
     996    {
     997        if (cchGraddChain1 > 0)
     998        {
     999            int idxGenGradd = -1;
     1000            for (size_t off = 0, idx = 0; off < cchGraddChain1;)
     1001            {
     1002                const char *psz = &pchGraddChain1[off];
     1003                size_t      cch = cchGraddChain1 - off;
     1004                const char *pszComma = (const char *)memchr(psz, ',', cchGraddChain1 - off);
     1005                if (!pszComma)
     1006                    off += cch;
     1007                else
     1008                {
     1009                    cch = pszComma - psz;
     1010                    off += cch + 1;
     1011                }
     1012                while (cch > 0 && RT_C_IS_BLANK(*psz))
     1013                    cch--, psz++;
     1014                while (cch > 0 && RT_C_IS_BLANK(psz[cch - 1]))
     1015                    cch--;
     1016                if (   cch == sizeof("GENGRADD") - 1
     1017                    && MyMemICmp(psz, RT_STR_TUPLE("GENGRADD")) == 0)
     1018                {
     1019                    idxGenGradd = idx;
     1020                    break;
     1021                }
     1022                idx += cch != 0;
     1023            }
     1024            if (idxGenGradd < 0)
     1025                return ErrorNStrings(RT_STR_TUPLE("Primary GRADD chain \""), pchGraddChains, cchGraddChains,
     1026                                     RT_STR_TUPLE("="), pchGraddChain1, cchGraddChain1,
     1027                                     RT_STR_TUPLE("\" does not contain a GENGRADD entry."), NULL, 0);
     1028            if (idxGenGradd != 0)
     1029                return ErrorNStrings(RT_STR_TUPLE("GENGRADD is not the first entry in the primary GRADD chain \""),
     1030                                     pchGraddChains, cchGraddChains, RT_STR_TUPLE("="), pchGraddChain1, cchGraddChain1, NULL, 0);
     1031        }
     1032        else if (cchGraddChains != 0)
     1033            return ErrorNStrings(RT_STR_TUPLE("Primary GRADD chain \""), pchGraddChains, cchGraddChains,
     1034                                 RT_STR_TUPLE("\" not found (only searched after SET GRADD_CHAINS)."), NULL, 0);
     1035        else
     1036            return ErrorNStrings(RT_STR_TUPLE("No SET GRADD_CHAINS statement found in Config.sys"), NULL, 0);
     1037    }
    8271038
    8281039    return RTEXITCODE_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette