Example #1
0
/**
 * Performs a case insensitive string compare between two UTF-8 strings, given a
 * maximum string length.
 *
 * This is a simplified compare, as only the simplified lower/upper case folding
 * specified by the unicode specs are used. It does not consider character pairs
 * as they are used in some languages, just simple upper & lower case compares.
 *
 * The result is the difference between the mismatching codepoints after they
 * both have been lower cased.
 *
 * If the string encoding is invalid the function will assert (strict builds)
 * and use RTStrCmp for the remainder of the string.
 *
 * @returns < 0 if the first string less than the second string.
 * @returns 0 if the first string identical to the second string.
 * @returns > 0 if the first string greater than the second string.
 * @param   psz1        First UTF-8 string. Null is allowed.
 * @param   psz2        Second UTF-8 string. Null is allowed.
 * @param   cchMax      Maximum string length
 */
RTDECL(int) RTStrNICmp(const char *psz1, const char *psz2, size_t cchMax)
{
    if (cchMax == 0)
        return 0;
    if (psz1 == psz2)
        return 0;
    if (!psz1)
        return -1;
    if (!psz2)
        return 1;

    for (;;)
    {
        /* Get the codepoints */
        RTUNICP uc1;
        size_t cchMax2 = cchMax;
        int rc = RTStrGetCpNEx(&psz1, &cchMax, &uc1);
        if (RT_FAILURE(rc))
        {
            AssertRC(rc);
            psz1--;
            cchMax++;
            break;
        }

        RTUNICP uc2;
        rc = RTStrGetCpNEx(&psz2, &cchMax2, &uc2);
        if (RT_FAILURE(rc))
        {
            AssertRC(rc);
            psz2--;
            psz1 -= (cchMax - cchMax2 + 1);  /* This can't overflow, can it? */
            cchMax = cchMax2 + 1;
            break;
        }

        /* compare */
        int iDiff = uc1 - uc2;
        if (iDiff)
        {
            iDiff = RTUniCpToUpper(uc1) != RTUniCpToUpper(uc2);
            if (iDiff)
            {
                iDiff = RTUniCpToLower(uc1) - RTUniCpToLower(uc2); /* lower case diff last! */
                if (iDiff)
                    return iDiff;
            }
        }

        /* hit the terminator? */
        if (!uc1 || cchMax == 0)
            return 0;
    }

    /* Hit some bad encoding, continue in case insensitive mode. */
    return RTStrNCmp(psz1, psz2, cchMax);
}
Example #2
0
bool getSequence(const char *pach, size_t cch, size_t *pcchRead,
                 const char *pcszSequence, size_t cchSequence)
{
    if (   cch - *pcchRead >= cchSequence
        && !RTStrNCmp(pach + *pcchRead, pcszSequence, cchSequence))
    {
        *pcchRead += cchSequence;
        return true;
    }
    return false;
}
RTDECL(RTCPUID) RTMpGetOnlineCoreCount(void)
{
    RTCPUID uOnlineCores = 0;
    int rc = RTOnceEx(&g_MpSolarisOnce, rtMpSolarisOnce, rtMpSolarisCleanUp, NULL /* pvUser */);
    if (RT_SUCCESS(rc))
    {
        rc = RTCritSectEnter(&g_MpSolarisCritSect);
        AssertRC(rc);

        /*
         * For each core in the system, count how many are currently online.
         */
        for (RTCPUID j = 0; j < g_cCores; j++)
        {
            uint64_t u64CoreId = g_pu64CoreIds[j];
            for (RTCPUID idCpu = 0; idCpu < g_capCpuInfo; idCpu++)
            {
                rc = kstat_read(g_pKsCtl, g_papCpuInfo[idCpu], 0);
                AssertReturn(rc != -1, 0 /* rc */);
                uint64_t u64ThreadCoreId = rtMpSolarisGetCoreId(idCpu);
                if (u64ThreadCoreId == u64CoreId)
                {
                    kstat_named_t *pStat = (kstat_named_t *)kstat_data_lookup(g_papCpuInfo[idCpu], (char *)"state");
                    Assert(pStat->data_type == KSTAT_DATA_CHAR);
                    if(   !RTStrNCmp(pStat->value.c, PS_ONLINE, sizeof(PS_ONLINE) - 1)
                       || !RTStrNCmp(pStat->value.c, PS_NOINTR, sizeof(PS_NOINTR) - 1))
                    {
                        uOnlineCores++;
                        break;      /* Move to the next core. We have at least 1 hyperthread online in the current core. */
                    }
                }
            }
        }

        RTCritSectLeave(&g_MpSolarisCritSect);
    }

    return uOnlineCores;
}
Example #4
0
File: tftp.c Project: ryenus/vbox
/**
 * This function evaluate file name.
 * @param pu8Payload
 * @param cbPayload
 * @param cbFileName
 * @return VINF_SUCCESS -
 *         VERR_INVALID_PARAMETER -
 */
DECLINLINE(int) tftpSecurityFilenameCheck(PNATState pData, PCTFTPSESSION pcTftpSession)
{
    size_t cbSessionFilename = 0;
    int rc = VINF_SUCCESS;
    AssertPtrReturn(pcTftpSession, VERR_INVALID_PARAMETER);
    cbSessionFilename = RTStrNLen((const char *)pcTftpSession->pszFilename, TFTP_FILENAME_MAX);
    if (   !RTStrNCmp((const char*)pcTftpSession->pszFilename, "../", 3)
        || (pcTftpSession->pszFilename[cbSessionFilename - 1] == '/')
        ||  RTStrStr((const char *)pcTftpSession->pszFilename, "/../"))
        rc = VERR_FILE_NOT_FOUND;

    /* only allow exported prefixes */
    if (   RT_SUCCESS(rc)
        && !tftp_prefix)
        rc = VERR_INTERNAL_ERROR;
    LogFlowFuncLeaveRC(rc);
    return rc;
}
RTDECL(int) RTPathCalcRelative(char *pszPathDst, size_t cbPathDst,
                               const char *pszPathFrom,
                               const char *pszPathTo)
{
    int rc = VINF_SUCCESS;

    AssertPtrReturn(pszPathDst, VERR_INVALID_POINTER);
    AssertReturn(cbPathDst, VERR_INVALID_PARAMETER);
    AssertPtrReturn(pszPathFrom, VERR_INVALID_POINTER);
    AssertPtrReturn(pszPathTo, VERR_INVALID_POINTER);
    AssertReturn(RTPathStartsWithRoot(pszPathFrom), VERR_INVALID_PARAMETER);
    AssertReturn(RTPathStartsWithRoot(pszPathTo), VERR_INVALID_PARAMETER);
    AssertReturn(RTStrCmp(pszPathFrom, pszPathTo), VERR_INVALID_PARAMETER);

    /*
     * Check for different root specifiers (drive letters), creating a relative path doesn't work here.
     * @todo: How to handle case insensitive root specifiers correctly?
     */
    size_t offRootFrom = rtPathRootSpecLen(pszPathFrom);
    size_t offRootTo   = rtPathRootSpecLen(pszPathTo);

    if (   offRootFrom != offRootTo
        || RTStrNCmp(pszPathFrom, pszPathTo, offRootFrom))
        return VERR_NOT_SUPPORTED;

    /* Filter out the parent path which is equal to both paths. */
    while (   *pszPathFrom == *pszPathTo
           && *pszPathFrom != '\0'
           && *pszPathTo != '\0')
    {
        pszPathFrom++;
        pszPathTo++;
    }

    /*
     * Because path components can start with an equal string but differ afterwards we
     * need to go back to the beginning of the current component.
     */
    while (!RTPATH_IS_SEP(*pszPathFrom))
        pszPathFrom--;

    pszPathFrom++; /* Skip path separator. */

    while (!RTPATH_IS_SEP(*pszPathTo))
        pszPathTo--;

    pszPathTo++; /* Skip path separator. */

    /* Paths point to the first non equal component now. */
    char aszPathTmp[RTPATH_MAX + 1];
    unsigned offPathTmp = 0;

    /* Create the part to go up from pszPathFrom. */
    while (*pszPathFrom != '\0')
    {
        while (   !RTPATH_IS_SEP(*pszPathFrom)
               && *pszPathFrom != '\0')
            pszPathFrom++;

        if (RTPATH_IS_SEP(*pszPathFrom))
        {
            if (offPathTmp + 3 >= sizeof(aszPathTmp) - 1)
                return VERR_FILENAME_TOO_LONG;
            aszPathTmp[offPathTmp++] = '.';
            aszPathTmp[offPathTmp++] = '.';
            aszPathTmp[offPathTmp++] = RTPATH_SLASH;
            pszPathFrom++;
        }
    }

    aszPathTmp[offPathTmp] = '\0';

    /* Now append the rest of pszPathTo to the final path. */
    char *pszPathTmp = &aszPathTmp[offPathTmp];
    size_t cbPathTmp = sizeof(aszPathTmp) - offPathTmp - 1;
    rc = RTStrCatP(&pszPathTmp, &cbPathTmp, pszPathTo);
    if (RT_SUCCESS(rc))
    {
        *pszPathTmp = '\0';

        size_t cchPathTmp = strlen(aszPathTmp);
        if (cchPathTmp >= cbPathDst)
           return VERR_BUFFER_OVERFLOW;
        memcpy(pszPathDst, aszPathTmp, cchPathTmp + 1);
    }
    else
        rc = VERR_FILENAME_TOO_LONG;

    return rc;
}
Example #6
0
/**
 * Parses a out the next block from a version string.
 *
 * @returns true if numeric, false if not.
 * @param   ppszVer             The string cursor, IN/OUT.
 * @param   pi32Value           Where to return the value if numeric.
 * @param   pcchBlock           Where to return the block length.
 */
static bool rtStrVersionParseBlock(const char **ppszVer, int32_t *pi32Value, size_t *pcchBlock)
{
    const char *psz = *ppszVer;

    /*
     * Check for end-of-string.
     */
    if (!*psz)
    {
        *pi32Value = 0;
        *pcchBlock = 0;
        return false;
    }

    /*
     * Try convert the block to a number the simple way.
     */
    char ch;
    bool fNumeric = RT_C_IS_DIGIT(*psz);
    if (fNumeric)
    {
        do
            ch = *++psz;
        while (ch && RT_C_IS_DIGIT(ch));

        int rc = RTStrToInt32Ex(*ppszVer, NULL, 10, pi32Value);
        if (RT_FAILURE(rc) || rc == VWRN_NUMBER_TOO_BIG)
        {
            AssertRC(rc);
            fNumeric = false;
            *pi32Value = 0;
        }
    }
    else
    {
        /*
         * Find the end of the current string.  Make a special case for SVN
         * revision numbers that immediately follows a release tag string.
         */
        do
            ch = *++psz;
        while (    ch
                   && !RT_C_IS_DIGIT(ch)
                   && !RTSTRVER_IS_PUNCTUACTION(ch));

        size_t cchBlock = psz - *ppszVer;
        if (   cchBlock > 1
                && psz[-1] == 'r'
                && RT_C_IS_DIGIT(*psz))
        {
            psz--;
            cchBlock--;
        }


        /*
         * Translate standard pre release terms to negative values.
         */
        static const struct
        {
            size_t      cch;
            const char *psz;
            int32_t     iValue;
        } s_aTerms[] =
        {
            { 2, "RC",      -100000 },
            { 3, "PRE",     -200000 },
            { 5, "GAMMA",   -300000 },
            { 4, "BETA",    -400000 },
            { 5, "ALPHA",   -500000 }
        };

        int32_t iVal1 = 0;
        for (unsigned i = 0; i < RT_ELEMENTS(s_aTerms); i++)
            if (   cchBlock == s_aTerms[i].cch
                    && !RTStrNCmp(s_aTerms[i].psz, *ppszVer, cchBlock))
            {
                iVal1 = s_aTerms[i].iValue;
                break;
            }
        if (iVal1 != 0)
        {
            /*
             * Does the prelease term have a trailing number?
             * Add it assuming BETA == BETA1.
             */
            if (RT_C_IS_DIGIT(*psz))
            {
                const char *psz2 = psz;
                do
                    ch = *++psz;
                while (   ch
                          && RT_C_IS_DIGIT(ch)
                          && !RTSTRVER_IS_PUNCTUACTION(ch));

                int rc = RTStrToInt32Ex(psz2, NULL, 10, pi32Value);
                if (RT_SUCCESS(rc) && rc != VWRN_NUMBER_TOO_BIG && *pi32Value)
                    iVal1 += *pi32Value - 1;
                else
                {
                    AssertRC(rc);
                    psz = psz2;
                }
            }
            fNumeric = true;
        }
        *pi32Value = iVal1;
    }
    *pcchBlock = psz - *ppszVer;

    /*
     * Skip trailing punctuation.
     */
    if (RTSTRVER_IS_PUNCTUACTION(*psz))
        psz++;
    *ppszVer = psz;

    return fNumeric;
}
/**
 * Get Parallel port address and update the shared data
 * structure.
 * @returns VBox status code.
 * @param   pThis    The host parallel port instance data.
 */
static int drvWinHostGetparportAddr(PDRVHOSTPARALLEL pThis)
{
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    uint32_t u32Idx;
    uint32_t u32ParportAddr;
    int rc = VINF_SUCCESS;

    hDevInfo = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES);
    if (hDevInfo == INVALID_HANDLE_VALUE)
        return VERR_INVALID_HANDLE;

    /* Enumerate through all devices in Set. */
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    for (u32Idx = 0; SetupDiEnumDeviceInfo(hDevInfo, u32Idx, &DeviceInfoData); u32Idx++)
    {
        DWORD dwDataType;
        uint8_t *pBuf = NULL;
        DWORD dwBufSize = 0;

        while (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME,
                                                 (PDWORD)&dwDataType, (uint8_t *)pBuf,
                                                 dwBufSize, (PDWORD)&dwBufSize))
        {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
            {
                LogFlow(("ERROR_INSUFF_BUFF = %d. dwBufSz = %d\n", GetLastError(), dwBufSize));
                if (pBuf)
                    RTMemFree(pBuf);
                pBuf = (uint8_t *)RTMemAlloc(dwBufSize * 2);
            }
            else
            {
                /* No need to bother about this error (in most cases its errno=13,
                 * INVALID_DATA . Just break from here and proceed to next device
                 * enumerated item
                 */
                LogFlow(("GetDevProp Error = %d & dwBufSz = %d\n", GetLastError(), dwBufSize));
                break;
            }
        }

        if (RTStrStr((char*)pBuf, "LPT"))
        {
            u32ParportAddr = drvHostWinFindIORangeResource(DeviceInfoData.DevInst);
            if (u32ParportAddr)
            {
                /* Find parallel port name and update the shared data struncture */
                char *pCh = RTStrStr((char*)pBuf, "(");
                char *pTmpCh = RTStrStr((char *)pBuf, ")");
                /* check for the confirmation for the availability of parallel port */
                if (!(pCh && pTmpCh))
                {
                    LogFlowFunc(("Parallel port Not Found. \n"));
                    return VERR_NOT_FOUND;

                }
                if (((pTmpCh - (char *)pBuf) - (pCh - (char *)pBuf)) < 0) {
                    LogFlowFunc(("Parallel port string not properly formatted.\n"));
                    return VERR_NOT_FOUND;
                }
                /* check for the confirmation for the availability of parallel port */
                if (RTStrCopyEx((char *)(pThis->szParportName), sizeof(pThis->szParportName),
                    pCh+1, ((pTmpCh - (char *)pBuf) - (pCh - (char *)pBuf)) - 1))
                {
                    LogFlowFunc(("Parallel Port Not Found.\n"));
                    return VERR_NOT_FOUND;
                }
                *((char *)pThis->szParportName + (pTmpCh - (char *)pBuf) - (pCh - (char *)pBuf) + 1 ) = '\0';

                /* checking again to make sure that we have got a valid name and in valid format too. */
                if (RTStrNCmp((char *)pThis->szParportName, "LPT", 3)) {
                    LogFlowFunc(("Parallel Port name \"LPT\" Not Found.\n"));
                    return VERR_NOT_FOUND;
                }
                if (!RTStrStr((char *)pThis->szParportName, "LPT")
                    || !(pThis->szParportName[3] >= '0'
                    && pThis->szParportName[3] <= '9'))
                {
                    RT_BZERO(pThis->szParportName, sizeof(pThis->szParportName));
                    LogFlowFunc(("Printer Port Name Not Found.\n"));
                    return VERR_NOT_FOUND;
                }
                pThis->fParportAvail     = true;
                pThis->u32LptAddr        = u32ParportAddr;
                pThis->u32LptAddrControl = pThis->u32LptAddr + CTRL_REG_OFFSET;
                pThis->u32LptAddrStatus  = pThis->u32LptAddr + STATUS_REG_OFFSET;
            }
            else
                LogFlowFunc(("u32Parport Addr No Available \n"));
            if (pThis->fParportAvail)
                break;
        }
        if (pBuf)
            RTMemFree(pBuf);
        if (pThis->fParportAvail)
        {
            /* Parallel port address has been found. No need to iterate further. */
            break;
        }
    }

    if (GetLastError() != NO_ERROR && GetLastError() != ERROR_NO_MORE_ITEMS)
        rc =  VERR_GENERAL_FAILURE;

    SetupDiDestroyDeviceInfoList(hDevInfo);
    return rc;

}
Example #8
0
 bool operator==(const PCIDeviceRecord &a) const
 {
     return RTStrNCmp(szDevName, a.szDevName, sizeof(szDevName)) == 0;
 }