Пример #1
0
/**
 * Formats a type using a registered callback handler.
 *
 * This will handle %R[type].
 *
 * @returns The number of bytes formatted.
 * @param   pfnOutput       Pointer to output function.
 * @param   pvArgOutput     Argument for the output function.
 * @param   ppszFormat      Pointer to the format string pointer. Advance this till the char
 *                          after the format specifier.
 * @param   pArgs           Pointer to the argument list. Use this to fetch the arguments.
 * @param   cchWidth        Format Width. -1 if not specified.
 * @param   cchPrecision    Format Precision. -1 if not specified.
 * @param   fFlags          Flags (RTSTR_NTFS_*).
 * @param   chArgSize       The argument size specifier, 'l' or 'L'.
 */
DECLHIDDEN(size_t) rtstrFormatType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat,
                                   va_list *pArgs, int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize)
{
    size_t      cch;
    int32_t     i;
    char const *pszTypeEnd;
    char const *pszType;
    char        ch;
    void       *pvValue = va_arg(*pArgs, void *);
    NOREF(chArgSize);

    /*
     * Parse out the type.
     */
    pszType = *ppszFormat + 2;
    *ppszFormat = pszType;
    Assert(pszType[-1] == '[');
    Assert(pszType[-2] == 'R');
    pszTypeEnd = pszType;
    while ((ch = *pszTypeEnd) != ']')
    {
        AssertReturn(ch != '\0', 0);
        AssertReturn(ch != '%', 0);
        AssertReturn(ch != '[', 0);
        pszTypeEnd++;
    }
    *ppszFormat = pszTypeEnd + 1;

    /*
     * Locate the entry and call the handler.
     */
    rtstrFormatTypeReadLock();

    i = rtstrFormatTypeLookup(pszType, pszTypeEnd - pszType);
    if (RT_LIKELY(i >= 0))
    {
#ifdef IN_RC
        PFNRTSTRFORMATTYPE pfnHandler = (PFNRTSTRFORMATTYPE)((intptr_t)&g_aTypes[0] + g_aTypes[i].offHandler);
#else
        PFNRTSTRFORMATTYPE pfnHandler = g_aTypes[i].pfnHandler;
#endif
        void *pvUser = ASMAtomicReadPtr(&g_aTypes[i].pvUser);

        rtstrFormatTypeReadUnlock();

        cch = pfnHandler(pfnOutput, pvArgOutput, g_aTypes[i].szType, pvValue, cchWidth, cchPrecision, fFlags, pvUser);
    }
    else
    {
        rtstrFormatTypeReadUnlock();

        cch  = pfnOutput(pvArgOutput, RT_STR_TUPLE("<missing:%R["));
        cch += pfnOutput(pvArgOutput, pszType, pszTypeEnd - pszType);
        cch += pfnOutput(pvArgOutput, RT_STR_TUPLE("]>"));
    }

    return cch;
}
Пример #2
0
int CollectorLinux::getDiskListByFs(const char *pszPath, DiskList& listUsage, DiskList& listLoad)
{
    FILE *mtab = setmntent("/etc/mtab", "r");
    if (mtab)
    {
        struct mntent *mntent;
        while ((mntent = getmntent(mtab)))
        {
            /* Skip rootfs entry, there must be another root mount. */
            if (strcmp(mntent->mnt_fsname, "rootfs") == 0)
                continue;
            if (strcmp(pszPath, mntent->mnt_dir) == 0)
            {
                char szDevName[128];
                char szFsName[1024];
                /* Try to resolve symbolic link if necessary. Yes, we access the file system here! */
                int rc = RTPathReal(mntent->mnt_fsname, szFsName, sizeof(szFsName));
                if (RT_FAILURE(rc))
                    continue; /* something got wrong, just ignore this path */
                /* check against the actual mtab entry, NOT the real path as /dev/mapper/xyz is
                 * often a symlink to something else */
                if (!strncmp(mntent->mnt_fsname, RT_STR_TUPLE("/dev/mapper")))
                {
                    /* LVM */
                    getDiskName(szDevName, sizeof(szDevName), mntent->mnt_fsname, false /*=fTrimDigits*/);
                    addVolumeDependencies(szDevName, listUsage);
                    listLoad = listUsage;
                }
                else if (!strncmp(szFsName, RT_STR_TUPLE("/dev/md")))
                {
                    /* Software RAID */
                    getDiskName(szDevName, sizeof(szDevName), szFsName, false /*=fTrimDigits*/);
                    listUsage.push_back(RTCString(szDevName));
                    addRaidDisks(szDevName, listLoad);
                }
                else
                {
                    /* Plain disk partition. Trim the trailing digits to get the drive name */
                    getDiskName(szDevName, sizeof(szDevName), szFsName, true /*=fTrimDigits*/);
                    listUsage.push_back(RTCString(szDevName));
                    listLoad.push_back(RTCString(szDevName));
                }
                if (listUsage.empty() || listLoad.empty())
                {
                    LogRel(("Failed to retrive disk info: getDiskName(%s) --> %s\n",
                           mntent->mnt_fsname, szDevName));
                }
                break;
            }
        }
        endmntent(mtab);
    }
    return VINF_SUCCESS;
}
Пример #3
0
RTR3DECL(int) RTHttpUseSystemProxySettings(RTHTTP hHttp)
{
    PRTHTTPINTERNAL pHttpInt = hHttp;
    RTHTTP_VALID_RETURN(pHttpInt);

    /*
     * Very limited right now, just enought to make it work for ourselves.
     */
    char szProxy[_1K];
    int rc = RTEnvGetEx(RTENV_DEFAULT, "http_proxy", szProxy, sizeof(szProxy), NULL);
    if (RT_SUCCESS(rc))
    {
        int rcCurl;
        if (!strncmp(szProxy, RT_STR_TUPLE("http://")))
        {
            rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_PROXY, &szProxy[sizeof("http://") - 1]);
            if (CURL_FAILED(rcCurl))
                return VERR_INVALID_PARAMETER;
            rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_PROXYPORT, 80);
            if (CURL_FAILED(rcCurl))
                return VERR_INVALID_PARAMETER;
        }
        else
        {
            rcCurl = curl_easy_setopt(pHttpInt->pCurl, CURLOPT_PROXY, &szProxy[sizeof("http://") - 1]);
            if (CURL_FAILED(rcCurl))
                return VERR_INVALID_PARAMETER;
        }
    }
    else if (rc == VERR_ENV_VAR_NOT_FOUND)
        rc = VINF_SUCCESS;

    return rc;
}
Пример #4
0
void CollectorLinux::addVolumeDependencies(const char *pcszVolume, DiskList& listDisks)
{
    char szVolInfo[RTPATH_MAX];
    int rc = RTPathAppPrivateArch(szVolInfo,
                                  sizeof(szVolInfo) - sizeof("/" VBOXVOLINFO_NAME " ") - strlen(pcszVolume));
    if (RT_FAILURE(rc))
    {
        LogRel(("VolInfo: Failed to get program path, rc=%Rrc\n", rc));
        return;
    }
    strcat(szVolInfo, "/" VBOXVOLINFO_NAME " ");
    strcat(szVolInfo, pcszVolume);

    FILE *fp = popen(szVolInfo, "r");
    if (fp)
    {
        char szBuf[128];

        while (fgets(szBuf, sizeof(szBuf), fp))
            if (strncmp(szBuf, RT_STR_TUPLE("dm-")))
                listDisks.push_back(RTCString(trimTrailingDigits(szBuf)));
            else
                listDisks.push_back(RTCString(trimNewline(szBuf)));

        pclose(fp);
    }
    else
        listDisks.push_back(RTCString(pcszVolume));
}
RTDECL(int) RTSystemQueryAvailableRam(uint64_t *pcb)
{
    AssertPtrReturn(pcb, VERR_INVALID_POINTER);

    FILE *pFile = fopen("/proc/meminfo", "r");
    if (pFile)
    {
        int rc = VERR_NOT_FOUND;
        uint64_t cbTotal = 0;
        uint64_t cbFree = 0;
        uint64_t cbBuffers = 0;
        uint64_t cbCached = 0;
        char sz[256];
        while (fgets(sz, sizeof(sz), pFile))
        {
            if (!strncmp(sz, RT_STR_TUPLE("MemTotal:")))
                rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("MemTotal:")]), NULL, 0, &cbTotal);
            else if (!strncmp(sz, RT_STR_TUPLE("MemFree:")))
                rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("MemFree:")]), NULL, 0, &cbFree);
            else if (!strncmp(sz, RT_STR_TUPLE("Buffers:")))
                rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("Buffers:")]), NULL, 0, &cbBuffers);
            else if (!strncmp(sz, RT_STR_TUPLE("Cached:")))
                rc = RTStrToUInt64Ex(RTStrStripL(&sz[sizeof("Cached:")]), NULL, 0, &cbCached);
            if (RT_FAILURE(rc))
                break;
        }
        fclose(pFile);
        if (RT_SUCCESS(rc))
        {
            *pcb = (cbFree + cbBuffers + cbCached) * _1K;
            return VINF_SUCCESS;
        }
    }
    /*
     * Fallback (e.g. /proc not mapped) to sysinfo. Less accurat because there
     * is no information about the cached memory. 'Cached:' from above is only
     * accessible through proc :-(
     */
    struct sysinfo info;
    int rc = sysinfo(&info);
    if (rc == 0)
    {
        *pcb = ((uint64_t)info.freeram + info.bufferram) * info.mem_unit;
        return VINF_SUCCESS;
    }
    return RTErrConvertFromErrno(errno);
}
Пример #6
0
int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list)
{
    char szDefaultIface[256];
    int rc = getDefaultIfaceName(szDefaultIface);
    if (RT_FAILURE(rc))
    {
        Log(("NetIfList: Failed to find default interface.\n"));
        szDefaultIface[0] = 0;
    }
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock >= 0)
    {
        FILE *fp = fopen("/proc/net/dev", "r");
        if (fp)
        {
            char buf[256];
            while (fgets(buf, sizeof(buf), fp))
            {
                char *pszEndOfName = strchr(buf, ':');
                if (!pszEndOfName)
                    continue;
                *pszEndOfName = 0;
                int iFirstNonWS = strspn(buf, " ");
                char *pszName = buf+iFirstNonWS;
                NETIFINFO Info;
                RT_ZERO(Info);
                rc = getInterfaceInfo(sock, pszName, &Info);
                if (RT_FAILURE(rc))
                    break;
                if (Info.enmMediumType == NETIF_T_ETHERNET)
                {
                    ComObjPtr<HostNetworkInterface> IfObj;
                    IfObj.createObject();

                    HostNetworkInterfaceType_T enmType;
                    if (strncmp(pszName, RT_STR_TUPLE("vboxnet")))
                        enmType = HostNetworkInterfaceType_Bridged;
                    else
                        enmType = HostNetworkInterfaceType_HostOnly;

                    if (SUCCEEDED(IfObj->init(Bstr(pszName), enmType, &Info)))
                    {
                        if (strcmp(pszName, szDefaultIface) == 0)
                            list.push_front(IfObj);
                        else
                            list.push_back(IfObj);
                    }
                }

            }
            fclose(fp);
        }
        close(sock);
    }
    else
        rc = VERR_INTERNAL_ERROR;

    return rc;
}
Пример #7
0
/**
 * Checkes for logger prefixes and selects the right logger.
 *
 * @returns Target logger.
 * @param   ppsz                Pointer to the string pointer.
 */
static PRTLOGGER dbgfR3LogResolvedLogger(const char **ppsz)
{
    PRTLOGGER   pLogger;
    const char *psz = *ppsz;
    if (!strncmp(psz, RT_STR_TUPLE("release:")))
    {
        *ppsz += sizeof("release:") - 1;
        pLogger = RTLogRelGetDefaultInstance();
    }
    else
    {
        if (!strncmp(psz, RT_STR_TUPLE("debug:")))
            *ppsz += sizeof("debug:") - 1;
        pLogger = RTLogDefaultInstance();
    }
    return pLogger;
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */
static DECLCALLBACK(int) rtDbgModDeferredDbg_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
                                                          PRTDBGSYMBOL pSymInfo)
{
    int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
    if (RT_SUCCESS(rc))
        rc = pMod->pDbgVt->pfnSymbolByName(pMod, pszSymbol, cchSymbol, pSymInfo);
    else
    {
        PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
        if (   cchSymbol             == sizeof("DeferredStart") - 1
             && !memcmp(pszSymbol, RT_STR_TUPLE("DeferredStart")))
            rc = rtDbgModDeferredDbgSymInfo_Start(pThis, pSymInfo);
        else if (   cchSymbol             == sizeof("DeferredLast") - 1
                 && !memcmp(pszSymbol, RT_STR_TUPLE("DeferredLast")))
            rc = rtDbgModDeferredDbgSymInfo_Last(pThis, pSymInfo);
        else
            rc = VERR_SYMBOL_NOT_FOUND;
    }
    return rc;
}
Пример #9
0
/**
 * Adds a debug file to the cache.
 *
 * @returns IPRT status code
 * @param   pszPath             The path to the debug file in question.
 * @param   pCfg                The configuration.
 */
static int rtDbgSymCacheAddDebugFile(const char *pszPath, PCRTDBGSYMCACHEADDCFG pCfg)
{
    /*
     * Need to extract an identifier of sorts here in order to put them in
     * the right place in the cache.  Currently only implemnted for Mach-O
     * files since these use executable containers.
     *
     * We take a look at the file header in hope to figure out what to do
     * with the file.
     */
    RTFILE hFile;
    int rc = RTFileOpen(&hFile, pszPath, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
    if (RT_FAILURE(rc))
        return RTMsgErrorRc(rc, "Error opening '%s': %Rrc", pszPath, rc);

    union
    {
        uint64_t au64[16];
        uint32_t au32[16];
        uint16_t au16[32];
        uint8_t  ab[64];
    } uBuf;
    rc = RTFileRead(hFile, &uBuf, sizeof(uBuf), NULL);
    if (RT_SUCCESS(rc))
    {
        /*
         * Look for magics and call workers.
         */
        if (!memcmp(uBuf.ab, RT_STR_TUPLE("Microsoft C/C++ MSF 7.00")))
            rc = rtDbgSymCacheAddDebugPdb(pszPath, pCfg, hFile);
        else if (   uBuf.au32[0] == IMAGE_FAT_SIGNATURE
                 || uBuf.au32[0] == IMAGE_FAT_SIGNATURE_OE
                 || uBuf.au32[0] == IMAGE_MACHO32_SIGNATURE
                 || uBuf.au32[0] == IMAGE_MACHO64_SIGNATURE
                 || uBuf.au32[0] == IMAGE_MACHO32_SIGNATURE_OE
                 || uBuf.au32[0] == IMAGE_MACHO64_SIGNATURE_OE)
            rc = rtDbgSymCacheAddDebugMachO(pszPath, pCfg);
        else
            rc = RTMsgErrorRc(VERR_INVALID_MAGIC, "Unsupported debug file '%s' magic: %#010x", pszPath, uBuf.au32[0]);
    }
    else
        rc = RTMsgErrorRc(rc, "Error reading '%s': %Rrc", pszPath, rc);

    /* close the file. */
    int rc2 = RTFileClose(hFile);
    if (RT_FAILURE(rc2))
    {
        RTMsgError("Error closing '%s': %Rrc", pszPath, rc2);
        if (RT_SUCCESS(rc))
            rc = rc2;
    }
    return rc;
}
Пример #10
0
/**
 * Internal worker that picks the processor speed in MHz from /proc/cpuinfo.
 *
 * @returns CPU frequency.
 */
static uint32_t rtMpLinuxGetFrequency(RTCPUID idCpu)
{
    FILE *pFile = fopen("/proc/cpuinfo", "r");
    if (!pFile)
        return 0;

    char sz[256];
    RTCPUID idCpuFound = NIL_RTCPUID;
    uint32_t Frequency = 0;
    while (fgets(sz, sizeof(sz), pFile))
    {
        char *psz;
        if (   !strncmp(sz, RT_STR_TUPLE("processor"))
            && (sz[10] == ' ' || sz[10] == '\t' || sz[10] == ':')
            && (psz = strchr(sz, ':')))
        {
            psz += 2;
            int64_t iCpu;
            int rc = RTStrToInt64Ex(psz, NULL, 0, &iCpu);
            if (RT_SUCCESS(rc))
                idCpuFound = iCpu;
        }
        else if (   idCpu == idCpuFound
                 && !strncmp(sz, RT_STR_TUPLE("cpu MHz"))
                 && (sz[10] == ' ' || sz[10] == '\t' || sz[10] == ':')
                 && (psz = strchr(sz, ':')))
        {
            psz += 2;
            int64_t v;
            int rc = RTStrToInt64Ex(psz, &psz, 0, &v);
            if (RT_SUCCESS(rc))
            {
                Frequency = v;
                break;
            }
        }
    }
    fclose(pFile);
    return Frequency;
}
static USBDEVICESTATE solarisDetermineUSBDeviceState(PUSBDEVICE pDevice, di_node_t Node)
{
    char *pszDriverName = di_driver_name(Node);

    /* Not possible unless a user explicitly unbinds the default driver. */
    if (!pszDriverName)
        return USBDEVICESTATE_UNUSED;

    if (!strncmp(pszDriverName, RT_STR_TUPLE(VBOXUSB_DRIVER_NAME)))
        return USBDEVICESTATE_HELD_BY_PROXY;

    NOREF(pDevice);
    return USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
}
/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */
static DECLCALLBACK(int) rtDbgModDeferredDbg_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
{
    int rc = rtDbgModDeferredDoIt(pMod, false /*fForceRetry*/);
    if (RT_SUCCESS(rc))
        rc = pMod->pDbgVt->pfnSegmentByIndex(pMod, iSeg, pSegInfo);
    else if (iSeg == 0)
    {
        PRTDBGMODDEFERRED pThis = (PRTDBGMODDEFERRED)pMod->pvDbgPriv;
        pSegInfo->Address   = 0;
        pSegInfo->uRva      = 0;
        pSegInfo->cb        = pThis->cbImage;
        pSegInfo->fFlags    = 0;
        pSegInfo->iSeg      = 0;
        memcpy(pSegInfo->szName, RT_STR_TUPLE("LATER"));
        rc = VINF_SUCCESS;
    }
    else
        rc = VERR_DBG_INVALID_SEGMENT_INDEX;
    return rc;
}
Пример #13
0
RTDECL(int) RTUriFilePathEx(const char *pszUri, uint32_t fPathStyle, char **ppszPath, size_t cbPath, size_t *pcchPath)
{
    /*
     * Validate and adjust input.
     */
    if (pcchPath)
    {
        AssertPtrReturn(pcchPath, VERR_INVALID_POINTER);
        *pcchPath = ~(size_t)0;
    }
    AssertPtrReturn(ppszPath, VERR_INVALID_POINTER);
    AssertReturn(!(fPathStyle & ~RTPATH_STR_F_STYLE_MASK) && fPathStyle != RTPATH_STR_F_STYLE_RESERVED, VERR_INVALID_FLAGS);
    if (fPathStyle == RTPATH_STR_F_STYLE_HOST)
        fPathStyle = RTPATH_STYLE;
    AssertPtrReturn(pszUri, VERR_INVALID_POINTER);

    /*
     * Check that this is a file URI.
     */
    if (RTStrNICmp(pszUri, RT_STR_TUPLE("file:")) == 0)
    { /* likely */ }
    else
        return VERR_URI_NOT_FILE_SCHEME;

    /*
     * We may have a number of variations here, mostly thanks to
     * various windows software.  First the canonical variations:
     *     - file:///C:/Windows/System32/kernel32.dll
     *     - file:///C|/Windows/System32/kernel32.dll
     *     - file:///C:%5CWindows%5CSystem32%5Ckernel32.dll
     *     - file://localhost/C:%5CWindows%5CSystem32%5Ckernel32.dll
     *     - file://cifsserver.dev/systemshare%5CWindows%5CSystem32%5Ckernel32.dll
     *     - file://cifsserver.dev:139/systemshare%5CWindows%5CSystem32%5Ckernel32.dll  (not quite sure here, but whatever)
     *
     * Legacy variant without any slashes after the schema:
     *     - file:C:/Windows/System32/kernel32.dll
     *     - file:C|/Windows/System32%5Ckernel32.dll
     *     - file:~/.bashrc
     *            \--path-/
     *
     * Legacy variant with exactly one slashes after the schema:
     *     - file:/C:/Windows/System32%5Ckernel32.dll
     *     - file:/C|/Windows/System32/kernel32.dll
     *     - file:/usr/bin/env
     *            \---path---/
     *
     * Legacy variant with two slashes after the schema and an unescaped DOS path:
     *     - file://C:/Windows/System32\kernel32.dll (**)
     *     - file://C|/Windows/System32\kernel32.dll
     *                \---path---------------------/
     *              -- authority, with ':' as non-working port separator
     *
     * Legacy variant with exactly four slashes after the schema and an unescaped DOS path.
     *     - file:////C:/Windows\System32\user32.dll
     *
     * Legacy variant with four or more slashes after the schema and an unescaped UNC path:
     *     - file:////cifsserver.dev/systemshare/System32%\kernel32.dll
     *     - file://///cifsserver.dev/systemshare/System32\kernel32.dll
     *              \---path--------------------------------------------/
     *
     * The the two unescaped variants shouldn't be handed to rtUriParse, which
     * is good as we cannot actually handle the one marked by (**).  So, handle
     * those two special when parsing.
     */
    RTURIPARSED Parsed;
    int         rc;
    size_t      cSlashes = 0;
    while (pszUri[5 + cSlashes] == '/')
        cSlashes++;
    if (   (cSlashes == 2 || cSlashes == 4)
        && RT_C_IS_ALPHA(pszUri[5 + cSlashes])
        && (pszUri[5 + cSlashes + 1] == ':' || pszUri[5 + cSlashes + 1] == '|'))
    {
        RT_ZERO(Parsed); /* RTURIPARSED_F_CONTAINS_ESCAPED_CHARS is now clear. */
        Parsed.offPath = 5 + cSlashes;
        Parsed.cchPath = strlen(&pszUri[Parsed.offPath]);
        rc = RTStrValidateEncoding(&pszUri[Parsed.offPath]);
    }
    else if (cSlashes >= 4)
    {
        RT_ZERO(Parsed);
        Parsed.fFlags  = cSlashes > 4 ? RTURIPARSED_F_CONTAINS_ESCAPED_CHARS : 0;
        Parsed.offPath = 5 + cSlashes - 2;
        Parsed.cchPath = strlen(&pszUri[Parsed.offPath]);
        rc = RTStrValidateEncoding(&pszUri[Parsed.offPath]);
    }
    else
        rc = rtUriParse(pszUri, &Parsed);
    if (RT_SUCCESS(rc))
    {
        /*
         * Ignore localhost as hostname (it's implicit).
         */
        static char const s_szLocalhost[] = "localhost";
        if (    Parsed.cchAuthorityHost == sizeof(s_szLocalhost) - 1U
            &&  RTStrNICmp(&pszUri[Parsed.offAuthorityHost], RT_STR_TUPLE(s_szLocalhost)) == 0)
        {
            Parsed.cchAuthorityHost = 0;
            Parsed.cchAuthority     = 0;
        }

        /*
         * Ignore leading path slash/separator if we detect a DOS drive letter
         * and we don't have a host name.
         */
        if (   Parsed.cchPath >= 3
            && Parsed.cchAuthorityHost    == 0
            && pszUri[Parsed.offPath]     == '/'           /* Leading path slash/separator. */
            && (   pszUri[Parsed.offPath + 2] == ':'       /* Colon after drive letter. */
                || pszUri[Parsed.offPath + 2] == '|')      /* Colon alternative. */
            && RT_C_IS_ALPHA(pszUri[Parsed.offPath + 1]) ) /* Drive letter. */
        {
            Parsed.offPath++;
            Parsed.cchPath--;
        }

        /*
         * Calculate the size of the encoded result.
         *
         * Since we're happily returning "C:/Windows/System32/kernel.dll"
         * style paths when the caller requested UNIX style paths, we will
         * return straight UNC paths too ("//cifsserver/share/dir/file").
         */
        size_t cchDecodedHost = 0;
        size_t cbResult;
        if (Parsed.fFlags & RTURIPARSED_F_CONTAINS_ESCAPED_CHARS)
        {
            cchDecodedHost = rtUriCalcDecodedLength(&pszUri[Parsed.offAuthorityHost], Parsed.cchAuthorityHost);
            cbResult = cchDecodedHost + rtUriCalcDecodedLength(&pszUri[Parsed.offPath], Parsed.cchPath) + 1;
        }
        else
        {
            cchDecodedHost = 0;
            cbResult = Parsed.cchAuthorityHost + Parsed.cchPath + 1;
        }
        if (pcchPath)
            *pcchPath = cbResult - 1;
        if (cbResult > 1)
        {
            /*
             * Prepare the necessary buffer space for the result.
             */
            char  *pszDst;
            char  *pszFreeMe = NULL;
            if (!cbPath || *ppszPath == NULL)
            {
                cbPath = RT_MAX(cbPath, cbResult);
                *ppszPath = pszFreeMe = pszDst = RTStrAlloc(cbPath);
                AssertReturn(pszDst, VERR_NO_STR_MEMORY);
            }
            else if (cbResult <= cbPath)
                pszDst = *ppszPath;
            else
                return VERR_BUFFER_OVERFLOW;

            /*
             * Compose the result.
             */
            if (Parsed.fFlags & RTURIPARSED_F_CONTAINS_ESCAPED_CHARS)
            {
                rc = rtUriDecodeIntoBuffer(&pszUri[Parsed.offAuthorityHost],Parsed.cchAuthorityHost,
                                           pszDst, cchDecodedHost + 1);
                Assert(RT_SUCCESS(rc) && strlen(pszDst) == cchDecodedHost);
                if (RT_SUCCESS(rc))
                    rc = rtUriDecodeIntoBuffer(&pszUri[Parsed.offPath], Parsed.cchPath,
                                               &pszDst[cchDecodedHost], cbResult - cchDecodedHost);
                Assert(RT_SUCCESS(rc) && strlen(pszDst) == cbResult - 1);
            }
            else
            {
                memcpy(pszDst, &pszUri[Parsed.offAuthorityHost], Parsed.cchAuthorityHost);
                memcpy(&pszDst[Parsed.cchAuthorityHost], &pszUri[Parsed.offPath], Parsed.cchPath);
                pszDst[cbResult - 1] = '\0';
            }
            if (RT_SUCCESS(rc))
            {
                /*
                 * Convert colon DOS driver letter colon alternative.
                 * We do this regardless of the desired path style.
                 */
                if (   RT_C_IS_ALPHA(pszDst[0])
                    && pszDst[1] == '|')
                    pszDst[1] = ':';

                /*
                 * Fix slashes.
                 */
                if (fPathStyle == RTPATH_STR_F_STYLE_DOS)
                    RTPathChangeToDosSlashes(pszDst, true);
                else if (fPathStyle == RTPATH_STR_F_STYLE_UNIX)
                    RTPathChangeToUnixSlashes(pszDst, true); /** @todo not quite sure how this actually makes sense... */
                else
                    AssertFailed();
                return rc;
            }

            /* bail out */
            RTStrFree(pszFreeMe);
        }
        else
            rc = VERR_PATH_ZERO_LENGTH;
    }
    return rc;
}
Пример #14
0
int main (int argc, char **argv)
{
#ifndef VBOX
    RTPrintf("tstSup: SKIPPED\n");
    return 0;
#else
    /*
     * Init.
     */
    RTTEST hTest;
    int rc = RTTestInitAndCreate("tstRTR0DbgKrnlInfo", &hTest);
    if (rc)
        return rc;
    RTTestBanner(hTest);

    uint8_t *pbPage = (uint8_t *)RTTestGuardedAllocTail(hTest, PAGE_SIZE);
    if (!pbPage)
    {
        RTTestFailed(hTest, "RTTestGuardedAllocTail failed with rc=%Rrc\n", rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    PSUPDRVSESSION pSession;
    rc = SUPR3Init(&pSession);
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "SUPR3Init failed with rc=%Rrc\n", rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    char szPath[RTPATH_MAX];
    rc = RTPathExecDir(szPath, sizeof(szPath));
    if (RT_SUCCESS(rc))
        rc = RTPathAppend(szPath, sizeof(szPath), "tstRTR0DbgKrnlInfo.r0");
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "Failed constructing .r0 filename (rc=%Rrc)", rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    void *pvImageBase;
    rc = SUPR3LoadServiceModule(szPath, "tstRTR0DbgKrnlInfo",
                                "TSTR0DbgKrnlInfoSrvReqHandler",
                                &pvImageBase);
    if (RT_FAILURE(rc))
    {
        RTTestFailed(hTest, "SUPR3LoadServiceModule(%s,,,) failed with rc=%Rrc\n", szPath, rc);
        return RTTestSummaryAndDestroy(hTest);
    }

    /* test request */
    struct
    {
        SUPR0SERVICEREQHDR  Hdr;
        char                szMsg[256];
    } Req;

    /*
     * Sanity checks.
     */
    RTTestSub(hTest, "Sanity");
    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
    Req.Hdr.cbReq = sizeof(Req);
    Req.szMsg[0] = '\0';
    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1,
                                             TSTRTR0DBGKRNLINFO_SANITY_OK, 0, &Req.Hdr), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return RTTestSummaryAndDestroy(hTest);
    RTTESTI_CHECK_MSG(Req.szMsg[0] == '\0', ("%s", Req.szMsg));
    if (Req.szMsg[0] != '\0')
        return RTTestSummaryAndDestroy(hTest);

    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
    Req.Hdr.cbReq = sizeof(Req);
    Req.szMsg[0] = '\0';
    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1,
                                             TSTRTR0DBGKRNLINFO_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return RTTestSummaryAndDestroy(hTest);
    RTTESTI_CHECK_MSG(!strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42")), ("%s", Req.szMsg));
    if (strncmp(Req.szMsg, RT_STR_TUPLE("!42failure42")))
        return RTTestSummaryAndDestroy(hTest);

    /*
     * Basic tests, bail out on failure.
     */
    RTTestSub(hTest, "Basics");
    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
    Req.Hdr.cbReq = sizeof(Req);
    Req.szMsg[0] = '\0';
    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0DbgKrnlInfo", sizeof("tstRTR0DbgKrnlInfo") - 1,
                                             TSTRTR0DBGKRNLINFO_BASIC, 0, &Req.Hdr), VINF_SUCCESS);
    if (RT_FAILURE(rc))
        return RTTestSummaryAndDestroy(hTest);
    if (Req.szMsg[0] == '!')
    {
        RTTestIFailed("%s", &Req.szMsg[1]);
        return RTTestSummaryAndDestroy(hTest);
    }
    if (Req.szMsg[0])
        RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", Req.szMsg);

    /*
     * Done.
     */
    return RTTestSummaryAndDestroy(hTest);
#endif
}
/*********************************************************************************************************************************
*   Header Files                                                                                                                 *
*********************************************************************************************************************************/
#include "internal/iprt.h"
#include <iprt/crypto/store.h>

#include <iprt/assert.h>
#include <iprt/err.h>
#include <iprt/crypto/pem.h>


/*********************************************************************************************************************************
*   Global Variables                                                                                                             *
*********************************************************************************************************************************/
static RTCRPEMMARKERWORD const g_aWords_Certificate[]  = { { RT_STR_TUPLE("CERTIFICATE") } };
/** X509 Certificate markers. */
static RTCRPEMMARKER     const g_aCertificateMarkers[] = { { g_aWords_Certificate, RT_ELEMENTS(g_aWords_Certificate) } };


#if 0
RTDECL(int) RTCrX509Certificates_ReadFromFile(const char *pszFilename, uint32_t fFlags,
                                              PRTCRX509CERTIFICATES pCertificates, PRTERRINFO pErrInfo)
{
    AssertReturn(!fFlags, VERR_INVALID_FLAGS);
    PCRTCRPEMSECTION pSectionHead;
    int rc = RTCrPemReadFile(pszFilename, 0, g_aCertificateMarkers, RT_ELEMENTS(g_aCertificateMarkers), &pSectionHead, pErrInfo);
    if (RT_SUCCESS(rc))
    {
        pCertificates->Allocation
/**
 * Corrects the casing of the final component
 *
 * @returns
 * @param   pClient             .
 * @param   pszFullPath         .
 * @param   pszStartComponent   .
 */
static int vbsfCorrectCasing(SHFLCLIENTDATA *pClient, char *pszFullPath, char *pszStartComponent)
{
    Log2(("vbsfCorrectCasing: %s %s\n", pszFullPath, pszStartComponent));

    AssertReturn((uintptr_t)pszFullPath < (uintptr_t)pszStartComponent - 1U, VERR_INTERNAL_ERROR_2);
    AssertReturn(pszStartComponent[-1] == RTPATH_DELIMITER, VERR_INTERNAL_ERROR_5);

    /*
     * Allocate a buffer that can hold really long file name entries as well as
     * the initial search pattern.
     */
    size_t cchComponent = strlen(pszStartComponent);
    size_t cchParentDir = pszStartComponent - pszFullPath;
    size_t cchFullPath  = cchParentDir + cchComponent;
    Assert(strlen(pszFullPath) == cchFullPath);

    size_t cbDirEntry   = 4096;
    if (cchFullPath + 4 > cbDirEntry - RT_OFFSETOF(RTDIRENTRYEX, szName))
        cbDirEntry = RT_OFFSETOF(RTDIRENTRYEX, szName) + cchFullPath + 4;

    PRTDIRENTRYEX pDirEntry = (PRTDIRENTRYEX)RTMemAlloc(cbDirEntry);
    if (pDirEntry == NULL)
        return VERR_NO_MEMORY;

    /*
     * Construct the search criteria in the szName member of pDirEntry.
     */
    /** @todo This is quite inefficient, especially for directories with many
     *        files.  If any of the typically case sensitive host systems start
     *        supporting opendir wildcard filters, it would make sense to build
     *        one here with '?' for case foldable charaters. */
    /** @todo Use RTDirOpen here and drop the whole uncessary path copying? */
    int rc = RTPathJoinEx(pDirEntry->szName, cbDirEntry - RT_OFFSETOF(RTDIRENTRYEX, szName),
                          pszFullPath, cchParentDir,
                          RT_STR_TUPLE("*"));
    AssertRC(rc);
    if (RT_SUCCESS(rc))
    {
        RTDIR hSearch = NULL;
        rc = RTDirOpenFiltered(&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT, 0 /*fFlags*/);
        if (RT_SUCCESS(rc))
        {
            for (;;)
            {
                size_t cbDirEntrySize = cbDirEntry;

                rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));
                if (rc == VERR_NO_MORE_FILES)
                    break;

                if (   rc != VINF_SUCCESS
                    && rc != VWRN_NO_DIRENT_INFO)
                {
                    if (   rc == VERR_NO_TRANSLATION
                        || rc == VERR_INVALID_UTF8_ENCODING)
                        continue;
                    AssertMsgFailed(("%Rrc\n", rc));
                    break;
                }

                Log2(("vbsfCorrectCasing: found %s\n", &pDirEntry->szName[0]));
                if (    pDirEntry->cbName == cchComponent
                    &&  !RTStrICmp(pszStartComponent, &pDirEntry->szName[0]))
                {
                    Log(("Found original name %s (%s)\n", &pDirEntry->szName[0], pszStartComponent));
                    strcpy(pszStartComponent, &pDirEntry->szName[0]);
                    rc = VINF_SUCCESS;
                    break;
                }
            }

            RTDirClose(hSearch);
        }
    }

    if (RT_FAILURE(rc))
        Log(("vbsfCorrectCasing %s failed with %Rrc\n", pszStartComponent, rc));

    RTMemFree(pDirEntry);

    return rc;
}
Пример #17
0
RTDECL(int) RTDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry,
                        RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags)
{
    int rc;

    /*
     * Validate input.
     */
    AssertPtrReturn(pDir, VERR_INVALID_POINTER);
    AssertReturn(pDir->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
    AssertPtrReturn(pDirEntry, VERR_INVALID_POINTER);

    AssertReturn(enmAdditionalAttribs >= RTFSOBJATTRADD_NOTHING && enmAdditionalAttribs <= RTFSOBJATTRADD_LAST,
                 VERR_INVALID_PARAMETER);
    AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER);

    size_t cbDirEntry = sizeof(*pDirEntry);
    if (pcbDirEntry)
    {
        cbDirEntry = *pcbDirEntry;
        AssertMsgReturn(cbDirEntry >= RT_UOFFSETOF(RTDIRENTRYEX, szName[2]),
                        ("Invalid *pcbDirEntry=%d (min %d)\n", *pcbDirEntry, RT_OFFSETOF(RTDIRENTRYEX, szName[2])),
                        VERR_INVALID_PARAMETER);
    }

    /*
     * Fetch data?
     */
    if (!pDir->fDataUnread)
    {
        rc = rtDirNtFetchMore(pDir);
        if (RT_FAILURE(rc))
            return rc;
    }

    /*
     * Convert the filename to UTF-8.
     */
    rc = rtDirNtConvertCurName(pDir);
    if (RT_FAILURE(rc))
        return rc;

    /*
     * Check if we've got enough space to return the data.
     */
    const char  *pszName    = pDir->pszName;
    const size_t cchName    = pDir->cchName;
    const size_t cbRequired = RT_OFFSETOF(RTDIRENTRYEX, szName[1]) + cchName;
    if (pcbDirEntry)
        *pcbDirEntry = cbRequired;
    if (cbRequired > cbDirEntry)
        return VERR_BUFFER_OVERFLOW;

    /*
     * Setup the returned data.
     */
    PFILE_BOTH_DIR_INFORMATION pBoth = pDir->uCurData.pBoth;

    pDirEntry->cbName  = (uint16_t)cchName;  Assert(pDirEntry->cbName == cchName);
    memcpy(pDirEntry->szName, pszName, cchName + 1);
    memset(pDirEntry->wszShortName, 0, sizeof(pDirEntry->wszShortName));
#ifdef IPRT_WITH_NT_PATH_PASSTHRU
    if (pDir->enmInfoClass != FileMaximumInformation)
#endif
    {
        uint8_t cbShort = pBoth->ShortNameLength;
        if (cbShort > 0)
        {
            AssertStmt(cbShort < sizeof(pDirEntry->wszShortName), cbShort = sizeof(pDirEntry->wszShortName) - 2);
            memcpy(pDirEntry->wszShortName, pBoth->ShortName, cbShort);
            pDirEntry->cwcShortName = cbShort / 2;
        }
        else
            pDirEntry->cwcShortName = 0;

        pDirEntry->Info.cbObject    = pBoth->EndOfFile.QuadPart;
        pDirEntry->Info.cbAllocated = pBoth->AllocationSize.QuadPart;

        Assert(sizeof(uint64_t) == sizeof(pBoth->CreationTime));
        RTTimeSpecSetNtTime(&pDirEntry->Info.BirthTime,         pBoth->CreationTime.QuadPart);
        RTTimeSpecSetNtTime(&pDirEntry->Info.AccessTime,        pBoth->LastAccessTime.QuadPart);
        RTTimeSpecSetNtTime(&pDirEntry->Info.ModificationTime,  pBoth->LastWriteTime.QuadPart);
        RTTimeSpecSetNtTime(&pDirEntry->Info.ChangeTime,        pBoth->ChangeTime.QuadPart);

        pDirEntry->Info.Attr.fMode  = rtFsModeFromDos((pBoth->FileAttributes << RTFS_DOS_SHIFT) & RTFS_DOS_MASK_NT,
                                                       pszName, cchName);
    }
#ifdef IPRT_WITH_NT_PATH_PASSTHRU
    else
    {
        pDirEntry->cwcShortName = 0;
        pDirEntry->Info.cbObject    = 0;
        pDirEntry->Info.cbAllocated = 0;
        RTTimeSpecSetNtTime(&pDirEntry->Info.BirthTime,         0);
        RTTimeSpecSetNtTime(&pDirEntry->Info.AccessTime,        0);
        RTTimeSpecSetNtTime(&pDirEntry->Info.ModificationTime,  0);
        RTTimeSpecSetNtTime(&pDirEntry->Info.ChangeTime,        0);

        if (rtNtCompWideStrAndAscii(pDir->uCurData.pObjDir->TypeName.Buffer, pDir->uCurData.pObjDir->TypeName.Length,
                                    RT_STR_TUPLE("Directory")))
            pDirEntry->Info.Attr.fMode = RTFS_DOS_DIRECTORY | RTFS_TYPE_DIRECTORY | 0777;
        else if (rtNtCompWideStrAndAscii(pDir->uCurData.pObjDir->TypeName.Buffer, pDir->uCurData.pObjDir->TypeName.Length,
                                         RT_STR_TUPLE("SymbolicLink")))
            pDirEntry->Info.Attr.fMode = RTFS_DOS_NT_REPARSE_POINT | RTFS_TYPE_SYMLINK | 0777;
        else if (rtNtCompWideStrAndAscii(pDir->uCurData.pObjDir->TypeName.Buffer, pDir->uCurData.pObjDir->TypeName.Length,
                                         RT_STR_TUPLE("Device")))
            pDirEntry->Info.Attr.fMode = RTFS_DOS_NT_DEVICE | RTFS_TYPE_DEV_CHAR | 0666;
        else
            pDirEntry->Info.Attr.fMode = RTFS_DOS_NT_NORMAL | RTFS_TYPE_FILE | 0666;
    }
#endif

    /*
     * Requested attributes (we cannot provide anything actually).
     */
    switch (enmAdditionalAttribs)
    {
        case RTFSOBJATTRADD_EASIZE:
            pDirEntry->Info.Attr.enmAdditional          = RTFSOBJATTRADD_EASIZE;
#ifdef IPRT_WITH_NT_PATH_PASSTHRU
            if (pDir->enmInfoClass == FileMaximumInformation)
                pDirEntry->Info.Attr.u.EASize.cb        = 0;
            else
#endif
                pDirEntry->Info.Attr.u.EASize.cb        = pBoth->EaSize;
            break;

        case RTFSOBJATTRADD_UNIX:
            pDirEntry->Info.Attr.enmAdditional          = RTFSOBJATTRADD_UNIX;
            pDirEntry->Info.Attr.u.Unix.uid             = ~0U;
            pDirEntry->Info.Attr.u.Unix.gid             = ~0U;
            pDirEntry->Info.Attr.u.Unix.cHardlinks      = 1;
            pDirEntry->Info.Attr.u.Unix.INodeIdDevice   = 0; /** @todo Use the volume serial number (see GetFileInformationByHandle). */
            pDirEntry->Info.Attr.u.Unix.INodeId         = 0; /** @todo Use the fileid (see GetFileInformationByHandle). */
            pDirEntry->Info.Attr.u.Unix.fFlags          = 0;
            pDirEntry->Info.Attr.u.Unix.GenerationId    = 0;
            pDirEntry->Info.Attr.u.Unix.Device          = 0;
            break;

        case RTFSOBJATTRADD_NOTHING:
            pDirEntry->Info.Attr.enmAdditional          = RTFSOBJATTRADD_NOTHING;
            break;

        case RTFSOBJATTRADD_UNIX_OWNER:
            pDirEntry->Info.Attr.enmAdditional          = RTFSOBJATTRADD_UNIX_OWNER;
            pDirEntry->Info.Attr.u.UnixOwner.uid        = ~0U;
            pDirEntry->Info.Attr.u.UnixOwner.szName[0]  = '\0'; /** @todo return something sensible here. */
            break;

        case RTFSOBJATTRADD_UNIX_GROUP:
            pDirEntry->Info.Attr.enmAdditional          = RTFSOBJATTRADD_UNIX_GROUP;
            pDirEntry->Info.Attr.u.UnixGroup.gid        = ~0U;
            pDirEntry->Info.Attr.u.UnixGroup.szName[0]  = '\0';
            break;

        default:
            AssertMsgFailed(("Impossible!\n"));
            return VERR_INTERNAL_ERROR;
    }

    /*
     * Follow links if requested.
     */
    if (   (fFlags & RTPATH_F_FOLLOW_LINK)
        && RTFS_IS_SYMLINK(fFlags))
    {
        /** @todo Symlinks: Find[First|Next]FileW will return info about
            the link, so RTPATH_F_FOLLOW_LINK is not handled correctly. */
    }

    /*
     * Finally advance the buffer.
     */
    return rtDirNtAdvanceBuffer(pDir);
}
Пример #18
0
RTDECL(int) RTDirRead(PRTDIR pDir, PRTDIRENTRY pDirEntry, size_t *pcbDirEntry)
{
    int rc;

    /*
     * Validate input.
     */
    AssertPtrReturn(pDir, VERR_INVALID_POINTER);
    AssertReturn(pDir->u32Magic == RTDIR_MAGIC, VERR_INVALID_HANDLE);
    AssertPtrReturn(pDirEntry, VERR_INVALID_POINTER);
    size_t cbDirEntry = sizeof(*pDirEntry);
    if (pcbDirEntry)
    {
        cbDirEntry = *pcbDirEntry;
        AssertMsgReturn(cbDirEntry >= RT_UOFFSETOF(RTDIRENTRY, szName[2]),
                        ("Invalid *pcbDirEntry=%d (min %d)\n", *pcbDirEntry, RT_OFFSETOF(RTDIRENTRY, szName[2])),
                        VERR_INVALID_PARAMETER);
    }

    /*
     * Fetch data?
     */
    if (!pDir->fDataUnread)
    {
        rc = rtDirNtFetchMore(pDir);
        if (RT_FAILURE(rc))
            return rc;
    }

    /*
     * Convert the filename to UTF-8.
     */
    rc = rtDirNtConvertCurName(pDir);
    if (RT_FAILURE(rc))
        return rc;

    /*
     * Check if we've got enough space to return the data.
     */
    const char  *pszName    = pDir->pszName;
    const size_t cchName    = pDir->cchName;
    const size_t cbRequired = RT_OFFSETOF(RTDIRENTRY, szName[1]) + cchName;
    if (pcbDirEntry)
        *pcbDirEntry = cbRequired;
    if (cbRequired > cbDirEntry)
        return VERR_BUFFER_OVERFLOW;

    /*
     * Setup the returned data.
     */
    pDirEntry->cbName = (uint16_t)cchName; Assert(pDirEntry->cbName == cchName);
    memcpy(pDirEntry->szName, pszName, cchName + 1);

    pDirEntry->INodeId = pDir->enmInfoClass == FileIdBothDirectoryInformation
                       ? pDir->uCurData.pBothId->FileId.QuadPart : 0;

#ifdef IPRT_WITH_NT_PATH_PASSTHRU
    if (pDir->enmInfoClass != FileMaximumInformation)
#endif
    {
        switch (   pDir->uCurData.pBoth->FileAttributes
                & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY))
        {
            default:
                AssertFailed();
            case 0:
                pDirEntry->enmType = RTDIRENTRYTYPE_FILE;
                break;

            case FILE_ATTRIBUTE_DIRECTORY:
                pDirEntry->enmType = RTDIRENTRYTYPE_DIRECTORY;
                break;

            case FILE_ATTRIBUTE_REPARSE_POINT:
            case FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY:
                pDirEntry->enmType = RTDIRENTRYTYPE_SYMLINK;
                break;
        }
    }
#ifdef IPRT_WITH_NT_PATH_PASSTHRU
    else
    {
        pDirEntry->enmType = RTDIRENTRYTYPE_UNKNOWN;
        if (rtNtCompWideStrAndAscii(pDir->uCurData.pObjDir->TypeName.Buffer, pDir->uCurData.pObjDir->TypeName.Length,
                                    RT_STR_TUPLE("Directory")))
            pDirEntry->enmType = RTDIRENTRYTYPE_DIRECTORY;
        else if (rtNtCompWideStrAndAscii(pDir->uCurData.pObjDir->TypeName.Buffer, pDir->uCurData.pObjDir->TypeName.Length,
                                         RT_STR_TUPLE("SymbolicLink")))
            pDirEntry->enmType = RTDIRENTRYTYPE_SYMLINK;
    }
#endif

    return rtDirNtAdvanceBuffer(pDir);
}
Пример #19
0
/**
 * One test iteration with one file.
 *
 * The test is very simple, we load the file three times
 * into two different regions. The first two into each of the
 * regions the for compare usage. The third is loaded into one
 * and then relocated between the two and other locations a few times.
 *
 * @returns number of errors.
 * @param   pszFilename     The file to load the mess with.
 */
static int testLdrOne(const char *pszFilename)
{
    int             cErrors = 0;
    size_t          cbImage = 0;
    struct Load
    {
        RTLDRMOD    hLdrMod;
        void       *pvBits;
        size_t      cbBits;
        const char *pszName;
    }   aLoads[6] =
    {
        { NULL, NULL, 0, "foo" },
        { NULL, NULL, 0, "bar" },
        { NULL, NULL, 0, "foobar" },
        { NULL, NULL, 0, "kLdr-foo" },
        { NULL, NULL, 0, "kLdr-bar" },
        { NULL, NULL, 0, "kLdr-foobar" }
    };
    unsigned i;
    int rc;

    /*
     * Load them.
     */
    for (i = 0; i < RT_ELEMENTS(aLoads); i++)
    {
        if (!strncmp(aLoads[i].pszName, RT_STR_TUPLE("kLdr-")))
            rc = RTLdrOpenkLdr(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod);
        else
            rc = RTLdrOpen(pszFilename, 0, RTLDRARCH_WHATEVER, &aLoads[i].hLdrMod);
        if (RT_FAILURE(rc))
        {
            RTPrintf("tstLdr-4: Failed to open '%s'/%d, rc=%Rrc. aborting test.\n", pszFilename, i, rc);
            Assert(aLoads[i].hLdrMod == NIL_RTLDRMOD);
            cErrors++;
            break;
        }

        /* size it */
        size_t cb = RTLdrSize(aLoads[i].hLdrMod);
        if (cbImage && cb != cbImage)
        {
            RTPrintf("tstLdr-4: Size mismatch '%s'/%d. aborting test.\n", pszFilename, i);
            cErrors++;
            break;
        }
        aLoads[i].cbBits = cbImage = cb;

        /* Allocate bits. */
        aLoads[i].pvBits = RTMemExecAlloc(cb);
        if (!aLoads[i].pvBits)
        {
            RTPrintf("tstLdr-4: Out of memory '%s'/%d cbImage=%d. aborting test.\n", pszFilename, i, cbImage);
            cErrors++;
            break;
        }

        /* Get the bits. */
        rc = RTLdrGetBits(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits, testGetImport, NULL);
        if (RT_FAILURE(rc))
        {
            RTPrintf("tstLdr-4: Failed to get bits for '%s'/%d, rc=%Rrc. aborting test\n", pszFilename, i, rc);
            cErrors++;
            break;
        }
    }

    /*
     * Execute the code.
     */
    if (!cErrors)
    {
        for (i = 0; i < RT_ELEMENTS(aLoads); i += 1)
        {
            /* get the pointer. */
            RTUINTPTR Value;
            rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits,
                                  UINT32_MAX, "DisasmTest1", &Value);
            if (rc == VERR_SYMBOL_NOT_FOUND)
                rc = RTLdrGetSymbolEx(aLoads[i].hLdrMod, aLoads[i].pvBits, (uintptr_t)aLoads[i].pvBits,
                                      UINT32_MAX, "_DisasmTest1", &Value);
            if (RT_FAILURE(rc))
            {
                RTPrintf("tstLdr-4: Failed to get symbol \"DisasmTest1\" from load #%d: %Rrc\n", i, rc);
                cErrors++;
                break;
            }
            DECLCALLBACKPTR(int, pfnDisasmTest1)(void) = (DECLCALLBACKPTR(int, RT_NOTHING)(void))(uintptr_t)Value; /* eeeh. */
            RTPrintf("tstLdr-4: pfnDisasmTest1=%p / add-symbol-file %s %#x\n", pfnDisasmTest1, pszFilename, aLoads[i].pvBits);

            /* call the test function. */
            rc = pfnDisasmTest1();
            if (rc)
            {
                RTPrintf("tstLdr-4: load #%d Test1 -> %#x\n", i, rc);
                cErrors++;
            }
        }
    }


    /*
     * Clean up.
     */
    for (i = 0; i < RT_ELEMENTS(aLoads); i++)
    {
        if (aLoads[i].pvBits)
            RTMemExecFree(aLoads[i].pvBits, aLoads[i].cbBits);
        if (aLoads[i].hLdrMod)
        {
            rc = RTLdrClose(aLoads[i].hLdrMod);
            if (RT_FAILURE(rc))
            {
                RTPrintf("tstLdr-4: Failed to close '%s' i=%d, rc=%Rrc.\n", pszFilename, i, rc);
                cErrors++;
            }
        }
    }

    return cErrors;
}
static int solarisWalkDeviceNode(di_node_t Node, void *pvArg)
{
    PUSBDEVICELIST pList = (PUSBDEVICELIST)pvArg;
    AssertPtrReturn(pList, DI_WALK_TERMINATE);

    /*
     * Check if it's a USB device in the first place.
     */
    bool fUSBDevice = false;
    char *pszCompatNames = NULL;
    int cCompatNames = di_compatible_names(Node, &pszCompatNames);
    for (int i = 0; i < cCompatNames; i++, pszCompatNames += strlen(pszCompatNames) + 1)
        if (!strncmp(pszCompatNames, RT_STR_TUPLE("usb")))
        {
            fUSBDevice = true;
            break;
        }

    if (!fUSBDevice)
        return DI_WALK_CONTINUE;

    /*
     * Check if it's a device node or interface.
     */
    int *pInt = NULL;
    char *pStr = NULL;
    int rc = DI_WALK_CONTINUE;
    if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "interface", &pInt) < 0)
    {
        /* It's a device node. */
        char *pszDevicePath = di_devfs_path(Node);
        PUSBDEVICE pCur = (PUSBDEVICE)RTMemAllocZ(sizeof(*pCur));
        if (!pCur)
        {
            LogRel(("USBService: failed to allocate %d bytes for PUSBDEVICE.\n", sizeof(*pCur)));
            return DI_WALK_TERMINATE;
        }

        bool fValidDevice = false;
        do
        {
            AssertBreak(pszDevicePath);

            char *pszDriverName = di_driver_name(Node);

            /*
             * Skip hubs
             */
            if (   pszDriverName
                && !strcmp(pszDriverName, "hubd"))
            {
                break;
            }

            /*
             * Mandatory.
             * snv_85 and above have usb-dev-descriptor node properties, but older one's do not.
             * So if we cannot obtain the entire device descriptor, we try falling back to the
             * individual properties (those must not fail, if it does we drop the device).
             */
            uchar_t *pDevData = NULL;
            int cbProp = di_prop_lookup_bytes(DDI_DEV_T_ANY, Node, "usb-dev-descriptor", &pDevData);
            if (   cbProp > 0
                && pDevData)
            {
                usb_dev_descr_t *pDeviceDescriptor = (usb_dev_descr_t *)pDevData;
                pCur->bDeviceClass = pDeviceDescriptor->bDeviceClass;
                pCur->bDeviceSubClass = pDeviceDescriptor->bDeviceSubClass;
                pCur->bDeviceProtocol = pDeviceDescriptor->bDeviceProtocol;
                pCur->idVendor = pDeviceDescriptor->idVendor;
                pCur->idProduct = pDeviceDescriptor->idProduct;
                pCur->bcdDevice = pDeviceDescriptor->bcdDevice;
                pCur->bcdUSB = pDeviceDescriptor->bcdUSB;
                pCur->bNumConfigurations = pDeviceDescriptor->bNumConfigurations;
                pCur->fPartialDescriptor = false;
            }
            else
            {
                AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-vendor-id", &pInt) > 0);
                pCur->idVendor = (uint16_t)*pInt;

                AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-product-id", &pInt) > 0);
                pCur->idProduct = (uint16_t)*pInt;

                AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-revision-id", &pInt) > 0);
                pCur->bcdDevice = (uint16_t)*pInt;

                AssertBreak(di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "usb-release", &pInt) > 0);
                pCur->bcdUSB = (uint16_t)*pInt;

                pCur->fPartialDescriptor = true;
            }

            char *pszPortAddr = di_bus_addr(Node);
            if (pszPortAddr)
                pCur->bPort = RTStrToUInt8(pszPortAddr);     /* Bus & Port are mixed up (kernel driver/userland) */
            else
                pCur->bPort = 0;

            char szBuf[PATH_MAX + 48];
            RTStrPrintf(szBuf, sizeof(szBuf), "%#x:%#x:%d:%s", pCur->idVendor, pCur->idProduct, pCur->bcdDevice, pszDevicePath);
            pCur->pszAddress = RTStrDup(szBuf);
            AssertBreak(pCur->pszAddress);

            pCur->pszDevicePath = RTStrDup(pszDevicePath);
            AssertBreak(pCur->pszDevicePath);

            pCur->pszBackend = RTStrDup("host");
            AssertBreak(pCur->pszBackend);

            /*
             * Optional (some devices don't have all these)
             */
            char *pszCopy;
            if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-product-name", &pStr) > 0)
            {
                pCur->pszProduct = pszCopy = RTStrDup(pStr);
                USBLibPurgeEncoding(pszCopy);
            }

            if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-vendor-name", &pStr) > 0)
            {
                pCur->pszManufacturer = pszCopy = RTStrDup(pStr);
                USBLibPurgeEncoding(pszCopy);
            }

            if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "usb-serialno", &pStr) > 0)
            {
                pCur->pszSerialNumber = pszCopy = RTStrDup(pStr);
                USBLibPurgeEncoding(pszCopy);
            }

            if (pCur->bcdUSB == 0x300)
                pCur->enmSpeed = USBDEVICESPEED_SUPER;
            else if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "low-speed", &pInt) >= 0)
                pCur->enmSpeed = USBDEVICESPEED_LOW;
            else if (di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "high-speed", &pInt) >= 0)
                pCur->enmSpeed = USBDEVICESPEED_HIGH;
            else
                pCur->enmSpeed = USBDEVICESPEED_FULL;

            /* Determine state of the USB device. */
            pCur->enmState = solarisDetermineUSBDeviceState(pCur, Node);

            /*
             * Valid device, add it to the list.
             */
            fValidDevice = true;
            pCur->pPrev = pList->pTail;
            if (pList->pTail)
                pList->pTail = pList->pTail->pNext = pCur;
            else
                pList->pTail = pList->pHead = pCur;

            rc = DI_WALK_CONTINUE;
        } while (0);

        di_devfs_path_free(pszDevicePath);
        if (!fValidDevice)
            solarisFreeUSBDevice(pCur);
    }
    return rc;
}
/**
 * Resolves imported functions, esp. system calls from NTDLL.
 *
 * This crap is necessary because there are sandboxing products out there that
 * will mess with system calls we make, just like any other wannabe userland
 * rootkit.  Kudos to microsoft for not providing a generic system call hook API
 * in the kernel mode, which I guess is what forcing these kind of products to
 * do ugly userland hacks that doesn't really hold water.
 */
DECLHIDDEN(void) supR3HardenedWinInitImports(void)
{
    /*
     * Find the DLLs we will be needing first (forwarders).
     */
    for (uint32_t iDll = 0; iDll < RT_ELEMENTS(g_aSupNtImpDlls); iDll++)
    {
        supR3HardenedFindOrLoadModule(&g_aSupNtImpDlls[iDll]);
        if (g_aSupNtImpDlls[iDll].pbImageBase)
            supR3HardenedParseModule(&g_aSupNtImpDlls[iDll]);
    }

    /*
     * Resolve the functions.
     */
    for (uint32_t iDll = 0; iDll < RT_ELEMENTS(g_aSupNtImpDlls); iDll++)
        for (uint32_t i = 0; i < g_aSupNtImpDlls[iDll].cImports; i++)
        {
            const char *pszForwarder = supR3HardenedResolveImport(&g_aSupNtImpDlls[iDll], &g_aSupNtImpDlls[iDll].paImports[i],
                                                                  false);
            if (pszForwarder)
            {
                const char *pszDot = strchr(pszForwarder, '.');
                size_t  cchDllName = pszDot - pszForwarder;
                SUPHNTIMPFUNC  Tmp = g_aSupNtImpDlls[iDll].paImports[i];
                Tmp.pszName = pszDot + 1;
                if (cchDllName == sizeof("ntdll") - 1 && RTStrNICmp(pszForwarder, RT_STR_TUPLE("ntdll")) == 0)
                    supR3HardenedResolveImport(&g_aSupNtImpDlls[0], &Tmp, false);
                else if (cchDllName == sizeof("kernelbase") - 1 && RTStrNICmp(pszForwarder, RT_STR_TUPLE("kernelbase")) == 0)
                    supR3HardenedResolveImport(&g_aSupNtImpDlls[1], &Tmp, false);
                else
                    SUPHNTIMP_ERROR(false, 18, "supR3HardenedWinInitImports", kSupInitOp_Misc, VERR_MODULE_NOT_FOUND,
                                    "%ls: Failed to resolve forwarder '%s'.", g_aSupNtImpDlls[iDll].pwszName, pszForwarder);
            }
        }

    /*
     * Do system calls directly.
     */
    supR3HardenedWinInitSyscalls(false);

    /*
     * Use the on disk image to avoid export table patching.  Currently
     * ignoring errors here as can live normally without this step.
     */
    for (uint32_t iDll = 0; iDll < RT_ELEMENTS(g_aSupNtImpDlls); iDll++)
        if (g_aSupNtImpDlls[iDll].cPatchedExports > 0)
        {
            PSUPHNTLDRCACHEENTRY pLdrEntry;
            int rc = supHardNtLdrCacheOpen(g_aSupNtImpDlls[iDll].pszName, &pLdrEntry);
            if (RT_SUCCESS(rc))
            {
                uint8_t *pbBits;
                rc = supHardNtLdrCacheEntryGetBits(pLdrEntry, &pbBits, (uintptr_t)g_aSupNtImpDlls[iDll].pbImageBase, NULL, NULL,
                                                   NULL /*pErrInfo*/);
                if (RT_SUCCESS(rc))
                    for (uint32_t i = 0; i < g_aSupNtImpDlls[iDll].cImports; i++)
                    {
                        RTLDRADDR uValue;
                        rc = RTLdrGetSymbolEx(pLdrEntry->hLdrMod, pbBits, (uintptr_t)g_aSupNtImpDlls[iDll].pbImageBase,
                                              UINT32_MAX, g_aSupNtImpDlls[iDll].paImports[i].pszName, &uValue);
                        if (RT_SUCCESS(rc))
                            *g_aSupNtImpDlls[iDll].paImports[i].ppfnImport = (PFNRT)(uintptr_t)uValue;
                    }
            }
        }


#if 0 /* Win7/32 ntdll!LdrpDebugFlags. */
    *(uint8_t *)&g_aSupNtImpDlls[0].pbImageBase[0xdd770] = 0x3;
#endif
}
/**
 * @callback_method_impl{FNRTSTRFORMATTYPE, vmsetcpu}
 */
static DECLCALLBACK(size_t) vmmFormatTypeVmCpuSet(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
                                                  const char *pszType, void const *pvValue,
                                                  int cchWidth, int cchPrecision, unsigned fFlags,
                                                  void *pvUser)
{
    NOREF(pszType); NOREF(cchWidth); NOREF(cchPrecision); NOREF(fFlags);

    PCVMCPUSET  pSet   = (PCVMCPUSET)pvValue;
    uint32_t    cCpus  = 0;
    uint32_t    iCpu   = RT_ELEMENTS(pSet->au32Bitmap) * 32;
    while (iCpu--)
        if (VMCPUSET_IS_PRESENT(pSet, iCpu))
            cCpus++;

    char szTmp[32];
    AssertCompile(RT_ELEMENTS(pSet->au32Bitmap) * 32 < 999);
    if (cCpus == 1)
    {
        iCpu = RT_ELEMENTS(pSet->au32Bitmap) * 32;
        while (iCpu--)
            if (VMCPUSET_IS_PRESENT(pSet, iCpu))
            {
                szTmp[0] = 'c';
                szTmp[1] = 'p';
                szTmp[2] = 'u';
                return pfnOutput(pvArgOutput, szTmp, 3 + vmmFormatTypeShortNumber(&szTmp[3], iCpu));
            }
        cCpus = 0;
    }
    if (cCpus == 0)
        return pfnOutput(pvArgOutput, RT_STR_TUPLE("<empty>"));
    if (cCpus == RT_ELEMENTS(pSet->au32Bitmap) * 32)
        return pfnOutput(pvArgOutput, RT_STR_TUPLE("<full>"));

    /*
     * Print cpus that are present: {1,2,7,9 ... }
     */
    size_t cchRet = pfnOutput(pvArgOutput, "{", 1);

    cCpus = 0;
    iCpu  = 0;
    while (iCpu < RT_ELEMENTS(pSet->au32Bitmap) * 32)
    {
        if (VMCPUSET_IS_PRESENT(pSet, iCpu))
        {
            /* Output the first cpu number. */
            int off = 0;
            if (cCpus != 0)
                szTmp[off++] = ',';
            off += vmmFormatTypeShortNumber(&szTmp[off], iCpu);

            /* Check for sequence. */
            uint32_t const iStart = ++iCpu;
            while (   iCpu < RT_ELEMENTS(pSet->au32Bitmap) * 32
                   && VMCPUSET_IS_PRESENT(pSet, iCpu))
                iCpu++;
            if (iCpu != iStart)
            {
                szTmp[off++] = '-';
                off += vmmFormatTypeShortNumber(&szTmp[off], iCpu);
            }

            /* Terminate and output. */
            szTmp[off] = '\0';
            cchRet += pfnOutput(pvArgOutput, szTmp, off);
        }
        iCpu++;
    }

    cchRet += pfnOutput(pvArgOutput, "}", 1);
    NOREF(pvUser);
    return cchRet;
}
Пример #23
0
int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list)
{
    int rc = VINF_SUCCESS;
    size_t cbNeeded;
    char *pBuf, *pNext;
    int aiMib[6];
    unsigned short u16DefaultIface = 0; /* initialized to shut up gcc */

    /* Get the index of the interface associated with default route. */
    rc = getDefaultIfaceIndex(&u16DefaultIface);
    if (RT_FAILURE(rc))
        return rc;

    aiMib[0] = CTL_NET;
    aiMib[1] = PF_ROUTE;
    aiMib[2] = 0;
    aiMib[3] = 0;       /* address family */
    aiMib[4] = NET_RT_IFLIST;
    aiMib[5] = 0;

    if (sysctl(aiMib, 6, NULL, &cbNeeded, NULL, 0) < 0)
    {
        Log(("NetIfList: Failed to get estimate for list size (errno=%d).\n", errno));
        return RTErrConvertFromErrno(errno);
    }
    if ((pBuf = (char*)RTMemAlloc(cbNeeded)) == NULL)
        return VERR_NO_MEMORY;
    if (sysctl(aiMib, 6, pBuf, &cbNeeded, NULL, 0) < 0)
    {
        RTMemFree(pBuf);
        Log(("NetIfList: Failed to retrieve interface table (errno=%d).\n", errno));
        return RTErrConvertFromErrno(errno);
    }

    int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (sock < 0)
    {
        RTMemFree(pBuf);
        Log(("NetIfList: socket() -> %d\n", errno));
        return RTErrConvertFromErrno(errno);
    }

    PDARWINETHERNIC pNIC;
    PDARWINETHERNIC pEtherNICs = DarwinGetEthernetControllers();

    char *pEnd = pBuf + cbNeeded;
    for (pNext = pBuf; pNext < pEnd;)
    {
        struct if_msghdr *pIfMsg = (struct if_msghdr *)pNext;

        if (pIfMsg->ifm_type != RTM_IFINFO)
        {
            Log(("NetIfList: Got message %u while expecting %u.\n",
                 pIfMsg->ifm_type, RTM_IFINFO));
            rc = VERR_INTERNAL_ERROR;
            break;
        }
        struct sockaddr_dl *pSdl = (struct sockaddr_dl *)(pIfMsg + 1);

        size_t cbNameLen = pSdl->sdl_nlen + 1;
        Assert(pSdl->sdl_nlen < sizeof(pNIC->szBSDName));
        for (pNIC = pEtherNICs; pNIC; pNIC = pNIC->pNext)
            if (   !strncmp(pSdl->sdl_data, pNIC->szBSDName, pSdl->sdl_nlen)
                && pNIC->szBSDName[pSdl->sdl_nlen] == '\0')
            {
                cbNameLen = strlen(pNIC->szName) + 1;
                break;
            }
        PNETIFINFO pNew = (PNETIFINFO)RTMemAllocZ(RT_OFFSETOF(NETIFINFO, szName[cbNameLen]));
        if (!pNew)
        {
            rc = VERR_NO_MEMORY;
            break;
        }
        memcpy(pNew->MACAddress.au8, LLADDR(pSdl), sizeof(pNew->MACAddress.au8));
        pNew->enmMediumType = NETIF_T_ETHERNET;
        Assert(sizeof(pNew->szShortName) > pSdl->sdl_nlen);
        memcpy(pNew->szShortName, pSdl->sdl_data, RT_MIN(pSdl->sdl_nlen, sizeof(pNew->szShortName) - 1));

        /*
         * If we found the adapter in the list returned by
         * DarwinGetEthernetControllers() copy the name and UUID from there.
         */
        if (pNIC)
        {
            memcpy(pNew->szName, pNIC->szName, cbNameLen);
            pNew->Uuid = pNIC->Uuid;
        }
        else
        {
            memcpy(pNew->szName, pSdl->sdl_data, pSdl->sdl_nlen);
            /* Generate UUID from name and MAC address. */
            RTUUID uuid;
            RTUuidClear(&uuid);
            memcpy(&uuid, pNew->szShortName, RT_MIN(cbNameLen, sizeof(uuid)));
            uuid.Gen.u8ClockSeqHiAndReserved = (uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80;
            uuid.Gen.u16TimeHiAndVersion = (uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000;
            memcpy(uuid.Gen.au8Node, pNew->MACAddress.au8, sizeof(uuid.Gen.au8Node));
            pNew->Uuid = uuid;
        }

        pNext += pIfMsg->ifm_msglen;
        while (pNext < pEnd)
        {
            struct ifa_msghdr *pIfAddrMsg = (struct ifa_msghdr *)pNext;

            if (pIfAddrMsg->ifam_type != RTM_NEWADDR)
                break;
            extractAddressesToNetInfo(pIfAddrMsg->ifam_addrs,
                                      (char *)(pIfAddrMsg + 1),
                                      pIfAddrMsg->ifam_msglen + (char *)pIfAddrMsg,
                                      pNew);
            pNext += pIfAddrMsg->ifam_msglen;
        }

        if (pSdl->sdl_type == IFT_ETHER)
        {
            struct ifreq IfReq;
            RTStrCopy(IfReq.ifr_name, sizeof(IfReq.ifr_name), pNew->szShortName);
            if (ioctl(sock, SIOCGIFFLAGS, &IfReq) < 0)
            {
                Log(("NetIfList: ioctl(SIOCGIFFLAGS) -> %d\n", errno));
                pNew->enmStatus = NETIF_S_UNKNOWN;
            }
            else
                pNew->enmStatus = (IfReq.ifr_flags & IFF_UP) ? NETIF_S_UP : NETIF_S_DOWN;

            HostNetworkInterfaceType_T enmType;
            if (strncmp(pNew->szName, RT_STR_TUPLE("vboxnet")))
                enmType = HostNetworkInterfaceType_Bridged;
            else
                enmType = HostNetworkInterfaceType_HostOnly;

            ComObjPtr<HostNetworkInterface> IfObj;
            IfObj.createObject();
            if (SUCCEEDED(IfObj->init(Bstr(pNew->szName), enmType, pNew)))
            {
                /* Make sure the default interface gets to the beginning. */
                if (pIfMsg->ifm_index == u16DefaultIface)
                    list.push_front(IfObj);
                else
                    list.push_back(IfObj);
            }
        }
        RTMemFree(pNew);
    }
    for (pNIC = pEtherNICs; pNIC;)
    {
        void *pvFree = pNIC;
        pNIC = pNIC->pNext;
        RTMemFree(pvFree);
    }
    close(sock);
    RTMemFree(pBuf);
    return rc;
}
Пример #24
0
// static
void ParsedIntervalFilter_base::parse (const char *aFilter,
                                       ParsedIntervalFilter_base *that)
{
    // initially null and valid
    that->mNull = true;
    that->mValid = true;
    that->mErrorPosition = 0;

    if (!aFilter || strncmp(aFilter, RT_STR_TUPLE("int:")) != 0)
        return;

    that->mNull = false;

    size_t len = strlen (aFilter);

    Mode mode = Single; // what's expected next
    size_t start = 4, end = 4;
    size_t err = 0; // less than 4 indicates success

    do
    {
        end = strcspn(aFilter + start, ",-");
        end += start;

        char delim = aFilter[end];

        if (delim == '-')
        {
            if (mode == End)
            {
                err = end;
                break;
            }
            else
                mode = Start;
        }

        // skip spaces around numbers
        size_t s = start;
        while (s < end && aFilter[s] == ' ') ++s;
        size_t e = end - 1;
        while (e > s && aFilter[e] == ' ') --e;
        ++e;

        that->parseValue(aFilter, s, e, mode);
        if (!that->mValid)
            return;

        if (mode == Start)
            mode = End;
        else if (mode == End)
            mode = Single;

        start = end + 1;
    }
    while (start <= len);

    if (err >= 4)
    {
        that->mValid = false;
        that->mErrorPosition = err;
    }
}
Пример #25
0
int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted, SUPINITOP *penmWhat, PRTERRINFO pErrInfo)
{
    /*
     * Make sure the image verifier is fully initialized.
     */
    int rc = suplibOsHardenedVerifyInit();
    if (RT_FAILURE(rc))
        return RTErrInfoSetF(pErrInfo, rc, "suplibOsHardenedVerifyInit failed: %Rrc", rc);

    /*
     * Done if of pre-inited.
     */
    if (fPreInited)
    {
#if defined(VBOX_WITH_HARDENING) && !defined(IN_SUP_HARDENED_R3)
# ifdef IN_SUP_R3_STATIC
        return VERR_NOT_SUPPORTED;
# else
        return VINF_SUCCESS;
# endif
#else
        return VINF_SUCCESS;
#endif
    }

    /*
     * Try open the device.
     */
#ifndef IN_SUP_HARDENED_R3
    uint32_t cTry = 0;
#endif
    HANDLE hDevice;
    for (;;)
    {
        IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;

        static const WCHAR  s_wszName[] = L"\\Device\\VBoxDrvU";
        UNICODE_STRING      NtName;
        NtName.Buffer        = (PWSTR)s_wszName;
        NtName.Length        = sizeof(s_wszName) - sizeof(WCHAR) * (fUnrestricted ? 2 : 1);
        NtName.MaximumLength = NtName.Length;

        OBJECT_ATTRIBUTES   ObjAttr;
        InitializeObjectAttributes(&ObjAttr, &NtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);

        hDevice = RTNT_INVALID_HANDLE_VALUE;

        NTSTATUS rcNt = NtCreateFile(&hDevice,
                                     GENERIC_READ | GENERIC_WRITE, /* No SYNCHRONIZE. */
                                     &ObjAttr,
                                     &Ios,
                                     NULL /* Allocation Size*/,
                                     FILE_ATTRIBUTE_NORMAL,
                                     FILE_SHARE_READ | FILE_SHARE_WRITE,
                                     FILE_OPEN,
                                     FILE_NON_DIRECTORY_FILE, /* No FILE_SYNCHRONOUS_IO_NONALERT! */
                                     NULL /*EaBuffer*/,
                                     0 /*EaLength*/);
        if (NT_SUCCESS(rcNt))
            rcNt = Ios.Status;
        if (NT_SUCCESS(rcNt))
        {
            /*
             * We're good.
             */
            pThis->hDevice       = hDevice;
            pThis->fUnrestricted = fUnrestricted;
            return VINF_SUCCESS;
        }

#ifndef IN_SUP_HARDENED_R3
        /*
         * Failed to open, try starting the service and reopen the device
         * exactly once.
         */
        if (cTry == 0 && !NT_SUCCESS(rcNt))
        {
            cTry++;
            suplibOsStartService();
            continue;
        }
#endif

        /*
         * Translate the error code.
         */
        switch (rcNt)
        {
            /** @todo someone must test what is actually returned. */
            case STATUS_DEVICE_DOES_NOT_EXIST:
            case STATUS_DEVICE_NOT_CONNECTED:
            //case ERROR_BAD_DEVICE:
            case STATUS_DEVICE_REMOVED:
            //case ERROR_DEVICE_NOT_AVAILABLE:
                rc = VERR_VM_DRIVER_LOAD_ERROR;
                break;
            case STATUS_OBJECT_PATH_NOT_FOUND:
            case STATUS_NO_SUCH_DEVICE:
            case STATUS_NO_SUCH_FILE:
            case STATUS_OBJECT_NAME_NOT_FOUND:
                rc = VERR_VM_DRIVER_NOT_INSTALLED;
                break;
            case STATUS_ACCESS_DENIED:
            case STATUS_SHARING_VIOLATION:
                rc = VERR_VM_DRIVER_NOT_ACCESSIBLE;
                break;
            case STATUS_UNSUCCESSFUL:
                rc = VERR_SUPLIB_NT_PROCESS_UNTRUSTED_0;
                break;
            case STATUS_TRUST_FAILURE:
                rc = VERR_SUPLIB_NT_PROCESS_UNTRUSTED_1;
                break;
            case STATUS_TOO_LATE:
                rc = VERR_SUPDRV_HARDENING_EVIL_HANDLE;
                break;
            default:
                if (SUP_NT_STATUS_IS_VBOX(rcNt)) /* See VBoxDrvNtErr2NtStatus. */
                    rc = SUP_NT_STATUS_TO_VBOX(rcNt);
                else
                    rc = VERR_VM_DRIVER_OPEN_ERROR;
                break;
        }

#ifdef IN_SUP_HARDENED_R3
        /*
         * Get more details from VBoxDrvErrorInfo if present.
         */
        if (pErrInfo && pErrInfo->cbMsg > 32)
        {
            /* Prefix. */
            size_t      cchPrefix;
            const char *pszDefine = RTErrGetDefine(rc);
            if (strncmp(pszDefine, RT_STR_TUPLE("Unknown")))
                cchPrefix = RTStrPrintf(pErrInfo->pszMsg, pErrInfo->cbMsg / 2, "Integrity error (%#x/%s): ", rcNt, pszDefine);
            else
                cchPrefix = RTStrPrintf(pErrInfo->pszMsg, pErrInfo->cbMsg / 2, "Integrity error (%#x/%d): ", rcNt, rc);

            /* Get error info. */
            supR3HardenedWinReadErrorInfoDevice(pErrInfo->pszMsg + cchPrefix, pErrInfo->cbMsg - cchPrefix, "");
            if (pErrInfo->pszMsg[cchPrefix] != '\0')
            {
                pErrInfo->fFlags |= RTERRINFO_FLAGS_SET;
                pErrInfo->rc      = rc;
                *penmWhat = kSupInitOp_Integrity;
            }
            else
                pErrInfo->pszMsg[0] = '\0';
        }
#endif
        return rc;
    }
}
    }

    /*
     * Not one of ours.
     */
    LeaveCriticalSection(&g_CritSect);
    return CloseHandle(hObject);
}




/** Replacement functions.   */
static const MSIHACKREPLACEMENT g_aReplaceFunctions[] =
{
    { RT_STR_TUPLE("CreateFileA"),          NULL,       (uintptr_t)MsiHack_Kernel32_CreateFileA },
    { RT_STR_TUPLE("CreateFileW"),          NULL,       (uintptr_t)MsiHack_Kernel32_CreateFileW },
    { RT_STR_TUPLE("ReadFile"),             NULL,       (uintptr_t)MsiHack_Kernel32_ReadFile },
    { RT_STR_TUPLE("ReadFileEx"),           NULL,       (uintptr_t)MsiHack_Kernel32_ReadFileEx },
    { RT_STR_TUPLE("SetFilePointer"),       NULL,       (uintptr_t)MsiHack_Kernel32_SetFilePointer },
    { RT_STR_TUPLE("SetFilePointerEx"),     NULL,       (uintptr_t)MsiHack_Kernel32_SetFilePointerEx },
    { RT_STR_TUPLE("DuplicateHandle"),      NULL,       (uintptr_t)MsiHack_Kernel32_DuplicateHandle },
    { RT_STR_TUPLE("CloseHandle"),          NULL,       (uintptr_t)MsiHack_Kernel32_CloseHandle },
};



/**
 * Patches the import table of the given DLL.
 *
 * @returns true on success, false on failure.
Пример #27
0
int main(int argc, char **argv)
{
     RTR3InitExe(argc, &argv, 0);

     RTDIGESTTYPE enmDigestType  = RTDIGESTTYPE_INVALID;
     const char  *pszDigestType  = "NotSpecified";

     enum
     {
         kMethod_Full,
         kMethod_Block,
         kMethod_File,
         kMethod_CVAS
     } enmMethod = kMethod_Block;

     uint64_t   offStart    = 0;
     uint64_t   cbMax       = UINT64_MAX;
     bool       fTestcase   = false;

     static const RTGETOPTDEF s_aOptions[] =
     {
         { "--type",   't', RTGETOPT_REQ_STRING },
         { "--method", 'm', RTGETOPT_REQ_STRING },
         { "--help",   'h', RTGETOPT_REQ_NOTHING },
         { "--length", 'l', RTGETOPT_REQ_UINT64 },
         { "--offset", 'o', RTGETOPT_REQ_UINT64 },
         { "--testcase", 'x', RTGETOPT_REQ_NOTHING },
     };

     int ch;
     RTGETOPTUNION ValueUnion;
     RTGETOPTSTATE GetState;
     RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     while ((ch = RTGetOpt(&GetState, &ValueUnion)))
     {
         switch (ch)
         {
             case 't':
                 if (!RTStrICmp(ValueUnion.psz, "crc32"))
                 {
                     pszDigestType  = "CRC32";
                     enmDigestType  = RTDIGESTTYPE_CRC32;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "crc64"))
                 {
                     pszDigestType = "CRC64";
                     enmDigestType = RTDIGESTTYPE_CRC64;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "md2"))
                 {
                     pszDigestType = "MD2";
                     enmDigestType = RTDIGESTTYPE_MD2;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "md5"))
                 {
                     pszDigestType = "MD5";
                     enmDigestType = RTDIGESTTYPE_MD5;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "sha1"))
                 {
                     pszDigestType = "SHA-1";
                     enmDigestType = RTDIGESTTYPE_SHA1;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "sha224"))
                 {
                     pszDigestType = "SHA-224";
                     enmDigestType = RTDIGESTTYPE_SHA224;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "sha256"))
                 {
                     pszDigestType = "SHA-256";
                     enmDigestType = RTDIGESTTYPE_SHA256;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "sha384"))
                 {
                     pszDigestType = "SHA-384";
                     enmDigestType = RTDIGESTTYPE_SHA384;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "sha512"))
                 {
                     pszDigestType = "SHA-512";
                     enmDigestType = RTDIGESTTYPE_SHA512;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "sha512/224"))
                 {
                     pszDigestType = "SHA-512/224";
                     enmDigestType = RTDIGESTTYPE_SHA512T224;
                 }
                 else if (!RTStrICmp(ValueUnion.psz, "sha512/256"))
                 {
                     pszDigestType = "SHA-512/256";
                     enmDigestType = RTDIGESTTYPE_SHA512T256;
                 }
                 else
                 {
                     Error("Invalid digest type: %s\n", ValueUnion.psz);
                     return 1;
                 }
                 break;

             case 'm':
                 if (!RTStrICmp(ValueUnion.psz, "full"))
                     enmMethod = kMethod_Full;
                 else if (!RTStrICmp(ValueUnion.psz, "block"))
                     enmMethod = kMethod_Block;
                 else if (!RTStrICmp(ValueUnion.psz, "file"))
                     enmMethod = kMethod_File;
                 else if (!RTStrICmp(ValueUnion.psz, "cvas"))
                     enmMethod = kMethod_CVAS;
                 else
                 {
                     Error("Invalid digest method: %s\n", ValueUnion.psz);
                     return 1;
                 }
                 break;

             case 'l':
                 cbMax = ValueUnion.u64;
                 break;

             case 'o':
                 offStart = ValueUnion.u64;
                 break;

             case 'x':
                 fTestcase = true;
                 break;

             case 'h':
                 RTPrintf("usage: tstRTDigest -t <digest-type> [-o <offset>] [-l <length>] [-x] file [file2 [..]]\n");
                 return 1;

             case VINF_GETOPT_NOT_OPTION:
             {
                 if (enmDigestType == RTDIGESTTYPE_INVALID)
                     return Error("No digest type was specified\n");

                 switch (enmMethod)
                 {
                     case kMethod_Full:
                         return Error("Full file method is not implemented\n");

                     case kMethod_File:
                         if (offStart != 0 || cbMax != UINT64_MAX)
                             return Error("The -l and -o options do not work with the 'file' method.");
                         switch (enmDigestType)
                         {
                             case RTDIGESTTYPE_SHA1:
                             {
                                 char *pszDigest;
                                 int rc = RTSha1DigestFromFile(ValueUnion.psz, &pszDigest, NULL, NULL);
                                 if (RT_FAILURE(rc))
                                     return Error("RTSha1Digest(%s,) -> %Rrc\n", ValueUnion.psz, rc);
                                 RTPrintf("%s  %s\n", pszDigest, ValueUnion.psz);
                                 RTStrFree(pszDigest);
                                 break;
                             }

                             case RTDIGESTTYPE_SHA256:
                             {
                                 char *pszDigest;
                                 int rc = RTSha256DigestFromFile(ValueUnion.psz, &pszDigest, NULL, NULL);
                                 if (RT_FAILURE(rc))
                                     return Error("RTSha256Digest(%s,) -> %Rrc\n", ValueUnion.psz, rc);
                                 RTPrintf("%s  %s\n", pszDigest, ValueUnion.psz);
                                 RTStrFree(pszDigest);
                                 break;
                             }
                             default:
                                 return Error("The file method isn't implemented for this digest\n");
                         }
                         break;

                     case kMethod_Block:
                     {
                         RTFILE hFile;
                         int rc = RTFileOpen(&hFile, ValueUnion.psz, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
                         if (RT_FAILURE(rc))
                             return Error("RTFileOpen(,%s,) -> %Rrc\n", ValueUnion.psz, rc);
                         if (offStart != 0)
                         {
                             rc = RTFileSeek(hFile, offStart, RTFILE_SEEK_BEGIN, NULL);
                             if (RT_FAILURE(rc))
                                 return Error("RTFileSeek(%s,%ull) -> %Rrc\n", ValueUnion.psz, offStart, rc);
                         }

                         uint64_t cbMaxLeft = cbMax;
                         size_t  cbRead;
                         uint8_t abBuf[_64K];
                         char   *pszDigest = (char *)&abBuf[0];
                         switch (enmDigestType)
                         {
                             case RTDIGESTTYPE_CRC32:
                             {
                                 uint32_t uCRC32 = RTCrc32Start();
                                 for (;;)
                                 {
                                     rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft);
                                     if (RT_FAILURE(rc) || !cbRead)
                                         break;
                                     uCRC32 = RTCrc32Process(uCRC32, abBuf, cbRead);
                                 }
                                 uCRC32 = RTCrc32Finish(uCRC32);
                                 RTStrPrintf(pszDigest, sizeof(abBuf), "%08RX32", uCRC32);
                                 break;
                             }

                             case RTDIGESTTYPE_CRC64:
                             {
                                 uint64_t uCRC64 = RTCrc64Start();
                                 for (;;)
                                 {
                                     rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft);
                                     if (RT_FAILURE(rc) || !cbRead)
                                         break;
                                     uCRC64 = RTCrc64Process(uCRC64, abBuf, cbRead);
                                 }
                                 uCRC64 = RTCrc64Finish(uCRC64);
                                 RTStrPrintf(pszDigest, sizeof(abBuf), "%016RX64", uCRC64);
                                 break;
                             }

                             case RTDIGESTTYPE_MD2:
                             {
                                 RTMD2CONTEXT Ctx;
                                 RTMd2Init(&Ctx);
                                 for (;;)
                                 {
                                     rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft);
                                     if (RT_FAILURE(rc) || !cbRead)
                                         break;
                                     RTMd2Update(&Ctx, abBuf, cbRead);
                                 }
                                 uint8_t abDigest[RTMD2_HASH_SIZE];
                                 RTMd2Final(&Ctx, abDigest);
                                 RTMd2ToString(abDigest, pszDigest, sizeof(abBuf));
                                 break;
                             }

                             case RTDIGESTTYPE_MD5:
                             {
                                 RTMD5CONTEXT Ctx;
                                 RTMd5Init(&Ctx);
                                 for (;;)
                                 {
                                     rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft);
                                     if (RT_FAILURE(rc) || !cbRead)
                                         break;
                                     RTMd5Update(&Ctx, abBuf, cbRead);
                                 }
                                 uint8_t abDigest[RTMD5HASHSIZE];
                                 RTMd5Final(abDigest, &Ctx);
                                 RTMd5ToString(abDigest, pszDigest, sizeof(abBuf));
                                 break;
                             }

                             case RTDIGESTTYPE_SHA1:
                             {
                                 RTSHA1CONTEXT Ctx;
                                 RTSha1Init(&Ctx);
                                 for (;;)
                                 {
                                     rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft);
                                     if (RT_FAILURE(rc) || !cbRead)
                                         break;
                                     RTSha1Update(&Ctx, abBuf, cbRead);
                                 }
                                 uint8_t abDigest[RTSHA1_HASH_SIZE];
                                 RTSha1Final(&Ctx, abDigest);
                                 RTSha1ToString(abDigest, pszDigest, sizeof(abBuf));
                                 break;
                             }

                             case RTDIGESTTYPE_SHA256:
                             {
                                 RTSHA256CONTEXT Ctx;
                                 RTSha256Init(&Ctx);
                                 for (;;)
                                 {
                                     rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft);
                                     if (RT_FAILURE(rc) || !cbRead)
                                         break;
                                     RTSha256Update(&Ctx, abBuf, cbRead);
                                 }
                                 uint8_t abDigest[RTSHA256_HASH_SIZE];
                                 RTSha256Final(&Ctx, abDigest);
                                 RTSha256ToString(abDigest, pszDigest, sizeof(abBuf));
                                 break;
                             }

                             case RTDIGESTTYPE_SHA512:
                             {
                                 RTSHA512CONTEXT Ctx;
                                 RTSha512Init(&Ctx);
                                 for (;;)
                                 {
                                     rc = MyReadFile(hFile, abBuf, sizeof(abBuf), &cbRead, &cbMaxLeft);
                                     if (RT_FAILURE(rc) || !cbRead)
                                         break;
                                     RTSha512Update(&Ctx, abBuf, cbRead);
                                 }
                                 uint8_t abDigest[RTSHA512_HASH_SIZE];
                                 RTSha512Final(&Ctx, abDigest);
                                 RTSha512ToString(abDigest, pszDigest, sizeof(abBuf));
                                 break;
                             }

                             default:
                                 return Error("Internal error #1\n");
                         }
                         RTFileClose(hFile);
                         if (RT_FAILURE(rc) && rc != VERR_EOF)
                         {
                             RTPrintf("Partial: %s  %s\n", pszDigest, ValueUnion.psz);
                             return Error("RTFileRead(%s) -> %Rrc\n", ValueUnion.psz, rc);
                         }

                         if (!fTestcase)
                             RTPrintf("%s  %s\n", pszDigest, ValueUnion.psz);
                         else if (offStart)
                             RTPrintf("        { &g_abRandom72KB[%#4llx], %5llu, \"%s\", \"%s %llu bytes @%llu\" },\n",
                                      offStart, cbMax - cbMaxLeft, pszDigest, pszDigestType, offStart, cbMax - cbMaxLeft);
                         else
                             RTPrintf("        { &g_abRandom72KB[0],     %5llu, \"%s\", \"%s %llu bytes\" },\n",
                                      cbMax - cbMaxLeft, pszDigest, pszDigestType, cbMax - cbMaxLeft);
                         break;
                     }


                     /*
                      * Process a SHS response file:
                      *     http://csrc.nist.gov/groups/STM/cavp/index.html#03
                      */
                     case kMethod_CVAS:
                     {
                         RTCRDIGEST hDigest;
                         int rc = RTCrDigestCreateByType(&hDigest, enmDigestType);
                         if (RT_FAILURE(rc))
                             return Error("Failed to create digest calculator for %s: %Rrc", pszDigestType, rc);

                         uint32_t const cbDigest = RTCrDigestGetHashSize(hDigest);
                         if (!cbDigest || cbDigest >= _1K)
                             return Error("Unexpected hash size: %#x\n", cbDigest);

                         PRTSTREAM pFile;
                         rc = RTStrmOpen(ValueUnion.psz, "r", &pFile);
                         if (RT_FAILURE(rc))
                             return Error("Failed to open CVAS file '%s': %Rrc", ValueUnion.psz, rc);

                         /*
                          * Parse the input file.
                          * ASSUME order: Len, Msg, MD.
                          */
                         static char    s_szLine[_256K];
                         char          *psz;
                         uint32_t       cPassed = 0;
                         uint32_t       cErrors = 0;
                         uint32_t       iLine   = 1;
                         for (;;)
                         {
                             psz = MyGetNextSignificantLine(pFile, s_szLine, sizeof(s_szLine), &iLine, &rc);
                             if (!psz)
                                 break;

                             /* Skip [L = 20] stuff. */
                             if (*psz == '[')
                                 continue;

                             /* Message length. */
                             uint64_t cMessageBits;
                             if (RTStrNICmp(psz, RT_STR_TUPLE("Len =")))
                                 return Error("%s(%d): Expected 'Len =' found '%.10s...'", ValueUnion.psz, iLine, psz);
                             psz = RTStrStripL(psz + 5);
                             rc = RTStrToUInt64Full(psz, 0, &cMessageBits);
                             if (rc != VINF_SUCCESS)
                                 return Error("%s(%d): Error parsing length '%s': %Rrc\n", ValueUnion.psz, iLine, psz, rc);

                             /* The message text. */
                             psz = MyGetNextSignificantLine(pFile, s_szLine, sizeof(s_szLine), &iLine, &rc);
                             if (!psz)
                                 return Error("%s(%d): Expected message text not EOF.", ValueUnion.psz, iLine);
                             if (RTStrNICmp(psz, RT_STR_TUPLE("Msg =")))
                                 return Error("%s(%d): Expected 'Msg =' found '%.10s...'", ValueUnion.psz, iLine, psz);
                             psz = RTStrStripL(psz + 5);

                             size_t const   cbMessage = (cMessageBits + 7) / 8;
                             static uint8_t s_abMessage[sizeof(s_szLine) / 2];
                             if (cbMessage > 0)
                             {
                                 rc = RTStrConvertHexBytes(psz, s_abMessage, cbMessage, 0 /*fFlags*/);
                                 if (rc != VINF_SUCCESS)
                                     return Error("%s(%d): Error parsing message '%.10s...': %Rrc\n",
                                                  ValueUnion.psz, iLine, psz, rc);
                             }

                             /* The message digest. */
                             psz = MyGetNextSignificantLine(pFile, s_szLine, sizeof(s_szLine), &iLine, &rc);
                             if (!psz)
                                 return Error("%s(%d): Expected message digest not EOF.", ValueUnion.psz, iLine);
                             if (RTStrNICmp(psz, RT_STR_TUPLE("MD =")))
                                 return Error("%s(%d): Expected 'MD =' found '%.10s...'", ValueUnion.psz, iLine, psz);
                             psz = RTStrStripL(psz + 4);

                             static uint8_t s_abExpectedDigest[_1K];
                             rc = RTStrConvertHexBytes(psz, s_abExpectedDigest, cbDigest, 0 /*fFlags*/);
                             if (rc != VINF_SUCCESS)
                                 return Error("%s(%d): Error parsing message digest '%.10s...': %Rrc\n",
                                              ValueUnion.psz, iLine, psz, rc);

                             /*
                              * Do the testing.
                              */
                             rc = RTCrDigestReset(hDigest);
                             if (rc != VINF_SUCCESS)
                                 return Error("RTCrDigestReset failed: %Rrc", rc);

                             rc = RTCrDigestUpdate(hDigest, s_abMessage, cbMessage);
                             if (rc != VINF_SUCCESS)
                                 return Error("RTCrDigestUpdate failed: %Rrc", rc);

                             static uint8_t s_abActualDigest[_1K];
                             rc = RTCrDigestFinal(hDigest, s_abActualDigest, cbDigest);
                             if (rc != VINF_SUCCESS)
                                 return Error("RTCrDigestFinal failed: %Rrc", rc);

                             if (memcmp(s_abActualDigest, s_abExpectedDigest, cbDigest) == 0)
                                 cPassed++;
                             else
                             {
                                 Error("%s(%d): Message digest mismatch. Expected %.*RThxs, got %.*RThxs.",
                                       ValueUnion.psz, iLine, cbDigest, s_abExpectedDigest, cbDigest, s_abActualDigest);
                                 cErrors++;
                             }
                         }

                         RTStrmClose(pFile);
                         if (cErrors > 0)
                             return Error("Failed: %u error%s (%u passed)", cErrors, cErrors == 1 ? "" : "s", cPassed);
                         RTPrintf("Passed %u test%s.\n", cPassed, cPassed == 1 ? "" : "s");
                         if (RT_FAILURE(rc))
                             return Error("Failed: %Rrc", rc);
                         break;
                     }

                     default:
                         return Error("Internal error #2\n");
                 }
                 break;
             }

             default:
                return RTGetOptPrintError(ch, &ValueUnion);
         }
     }

     return 0;
}
Пример #28
0
*   Global Variables                                                                                                             *
*********************************************************************************************************************************/
/**
 * VMM trace point group translation table.
 */
static const struct
{
    /** The group name. */
    const char *pszName;
    /** The name length. */
    uint32_t    cchName;
    /** The mask. */
    uint32_t    fMask;
}   g_aVmmTpGroups[] =
{
    {  RT_STR_TUPLE("em"), VMMTPGROUP_EM },
    {  RT_STR_TUPLE("hm"), VMMTPGROUP_HM },
    {  RT_STR_TUPLE("tm"), VMMTPGROUP_TM },
};


/**
 * Initializes the tracing.
 *
 * @returns VBox status code
 * @param   pVM         The cross context VM structure.
 * @param   cbEntry     The trace entry size.
 * @param   cEntries    The number of entries.
 */
static int dbgfR3TraceEnable(PVM pVM, uint32_t cbEntry, uint32_t cEntries)
{
Пример #29
0
int main(int argc, char **argv)
{
    RTEXITCODE rcExit;

    /*
     * Init globals and such.
     */
    int rc = RTR3InitExe(argc, &argv, 0);
    if (RT_FAILURE(rc))
        return RTMsgInitFailure(rc);
    g_pszProgName = RTPathFilename(argv[0]);
#ifdef DEBUG
    rc = RTCritSectInit(&g_csLog);
    AssertRC(rc);
#endif

#ifdef VBOXSERVICE_TOOLBOX
    /*
     * Run toolbox code before all other stuff since these things are simpler
     * shell/file/text utility like programs that just happens to be inside
     * VBoxService and shouldn't be subject to /dev/vboxguest, pid-files and
     * global mutex restrictions.
     */
    if (VBoxServiceToolboxMain(argc, argv, &rcExit))
        return rcExit;
#endif

    bool fUserSession = false;
#ifdef VBOX_WITH_GUEST_CONTROL
    /*
     * Check if we're the specially spawned VBoxService.exe process that
     * handles a guest control session.
     */
    if (   argc >= 2
        && !RTStrICmp(argv[1], "guestsession"))
        fUserSession = true;
#endif

    /*
     * Connect to the kernel part before daemonizing so we can fail and
     * complain if there is some kind of problem.  We need to initialize the
     * guest lib *before* we do the pre-init just in case one of services needs
     * do to some initial stuff with it.
     */
    if (fUserSession)
        rc = VbglR3InitUser();
    else
        rc = VbglR3Init();

    if (RT_FAILURE(rc))
    {
        if (rc == VERR_ACCESS_DENIED)
            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Insufficient privileges to start %s! Please start with Administrator/root privileges!\n",
                                  g_pszProgName);
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "VbglR3Init failed with rc=%Rrc\n", rc);
    }

#ifdef RT_OS_WINDOWS
    /*
     * Check if we're the specially spawned VBoxService.exe process that
     * handles page fusion.  This saves an extra executable.
     */
    if (   argc == 2
        && !RTStrICmp(argv[1], "pagefusion"))
        return VBoxServicePageSharingWorkerChild();
#endif

#ifdef VBOX_WITH_GUEST_CONTROL
    /*
     * Check if we're the specially spawned VBoxService.exe process that
     * handles a guest control session.
     */
    if (fUserSession)
        return VBoxServiceControlSessionForkInit(argc, argv);
#endif

    /*
     * Parse the arguments.
     *
     * Note! This code predates RTGetOpt, thus the manual parsing.
     */
    bool fDaemonize = true;
    bool fDaemonized = false;
    for (int i = 1; i < argc; i++)
    {
        const char *psz = argv[i];
        if (*psz != '-')
            return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown argument '%s'\n", psz);
        psz++;

        /* translate long argument to short */
        if (*psz == '-')
        {
            psz++;
            size_t cch = strlen(psz);
#define MATCHES(strconst)       (   cch == sizeof(strconst) - 1 \
                                 && !memcmp(psz, strconst, sizeof(strconst) - 1) )
            if (MATCHES("foreground"))
                psz = "f";
            else if (MATCHES("verbose"))
                psz = "v";
            else if (MATCHES("version"))
                psz = "V";
            else if (MATCHES("help"))
                psz = "h";
            else if (MATCHES("interval"))
                psz = "i";
#ifdef RT_OS_WINDOWS
            else if (MATCHES("register"))
                psz = "r";
            else if (MATCHES("unregister"))
                psz = "u";
#endif
            else if (MATCHES("logfile"))
                psz = "l";
            else if (MATCHES("daemonized"))
            {
                fDaemonized = true;
                continue;
            }
            else
            {
                bool fFound = false;

                if (cch > sizeof("enable-") && !memcmp(psz, RT_STR_TUPLE("enable-")))
                    for (unsigned j = 0; !fFound && j < RT_ELEMENTS(g_aServices); j++)
                        if ((fFound = !RTStrICmp(psz + sizeof("enable-") - 1, g_aServices[j].pDesc->pszName)))
                            g_aServices[j].fEnabled = true;

                if (cch > sizeof("disable-") && !memcmp(psz, RT_STR_TUPLE("disable-")))
                    for (unsigned j = 0; !fFound && j < RT_ELEMENTS(g_aServices); j++)
                        if ((fFound = !RTStrICmp(psz + sizeof("disable-") - 1, g_aServices[j].pDesc->pszName)))
                            g_aServices[j].fEnabled = false;

                if (cch > sizeof("only-") && !memcmp(psz, RT_STR_TUPLE("only-")))
                    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
                    {
                        g_aServices[j].fEnabled = !RTStrICmp(psz + sizeof("only-") - 1, g_aServices[j].pDesc->pszName);
                        if (g_aServices[j].fEnabled)
                            fFound = true;
                    }

                if (!fFound)
                {
                    rcExit = vboxServiceLazyPreInit();
                    if (rcExit != RTEXITCODE_SUCCESS)
                        return rcExit;
                    for (unsigned j = 0; !fFound && j < RT_ELEMENTS(g_aServices); j++)
                    {
                        rc = g_aServices[j].pDesc->pfnOption(NULL, argc, argv, &i);
                        fFound = rc == VINF_SUCCESS;
                        if (fFound)
                            break;
                        if (rc != -1)
                            return rc;
                    }
                }
                if (!fFound)
                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option '%s'\n", argv[i]);
                continue;
            }
#undef MATCHES
        }

        /* handle the string of short options. */
        do
        {
            switch (*psz)
            {
                case 'i':
                    rc = VBoxServiceArgUInt32(argc, argv, psz + 1, &i,
                                              &g_DefaultInterval, 1, (UINT32_MAX / 1000) - 1);
                    if (rc)
                        return rc;
                    psz = NULL;
                    break;

                case 'f':
                    fDaemonize = false;
                    break;

                case 'v':
                    g_cVerbosity++;
                    break;

                case 'V':
                    RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
                    return RTEXITCODE_SUCCESS;

                case 'h':
                case '?':
                    return vboxServiceUsage();

#ifdef RT_OS_WINDOWS
                case 'r':
                    return VBoxServiceWinInstall();

                case 'u':
                    return VBoxServiceWinUninstall();
#endif

                case 'l':
                {
                    rc = VBoxServiceArgString(argc, argv, psz + 1, &i,
                                              g_szLogFile, sizeof(g_szLogFile));
                    if (rc)
                        return rc;
                    psz = NULL;
                    break;
                }

                default:
                {
                    rcExit = vboxServiceLazyPreInit();
                    if (rcExit != RTEXITCODE_SUCCESS)
                        return rcExit;

                    bool fFound = false;
                    for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++)
                    {
                        rc = g_aServices[j].pDesc->pfnOption(&psz, argc, argv, &i);
                        fFound = rc == VINF_SUCCESS;
                        if (fFound)
                            break;
                        if (rc != -1)
                            return rc;
                    }
                    if (!fFound)
                        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown option '%c' (%s)\n", *psz, argv[i]);
                    break;
                }
            }
        } while (psz && *++psz);
    }

    /* Check that at least one service is enabled. */
    if (vboxServiceCountEnabledServices() == 0)
        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "At least one service must be enabled\n");

    rc = VBoxServiceLogCreate(strlen(g_szLogFile) ? g_szLogFile : NULL);
    if (RT_FAILURE(rc))
        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create release log \"%s\", rc=%Rrc\n",
                              strlen(g_szLogFile) ? g_szLogFile : "<None>", rc);

    /* Call pre-init if we didn't do it already. */
    rcExit = vboxServiceLazyPreInit();
    if (rcExit != RTEXITCODE_SUCCESS)
        return rcExit;

#ifdef RT_OS_WINDOWS
    /*
     * Make sure only one instance of VBoxService runs at a time.  Create a
     * global mutex for that.
     *
     * Note! The \\Global\ namespace was introduced with Win2K, thus the
     *       version check.
     * Note! If the mutex exists CreateMutex will open it and set last error to
     *       ERROR_ALREADY_EXISTS.
     */
    OSVERSIONINFOEX OSInfoEx;
    RT_ZERO(OSInfoEx);
    OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

    SetLastError(NO_ERROR);
    HANDLE hMutexAppRunning;
    if (    GetVersionEx((LPOSVERSIONINFO)&OSInfoEx)
        &&  OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT
        &&  OSInfoEx.dwMajorVersion >= 5 /* NT 5.0 a.k.a W2K */)
        hMutexAppRunning = CreateMutex(NULL, FALSE, "Global\\" VBOXSERVICE_NAME);
    else
        hMutexAppRunning = CreateMutex(NULL, FALSE, VBOXSERVICE_NAME);
    if (hMutexAppRunning == NULL)
    {
        DWORD dwErr = GetLastError();
        if (   dwErr == ERROR_ALREADY_EXISTS
            || dwErr == ERROR_ACCESS_DENIED)
        {
            VBoxServiceError("%s is already running! Terminating.\n", g_pszProgName);
            return RTEXITCODE_FAILURE;
        }

        VBoxServiceError("CreateMutex failed with last error %u! Terminating.\n", GetLastError());
        return RTEXITCODE_FAILURE;
    }

#else  /* !RT_OS_WINDOWS */
    /** @todo Add PID file creation here? */
#endif /* !RT_OS_WINDOWS */

    VBoxServiceVerbose(0, "%s r%s started. Verbose level = %d\n",
                       RTBldCfgVersion(), RTBldCfgRevisionStr(), g_cVerbosity);

    /*
     * Daemonize if requested.
     */
    if (fDaemonize && !fDaemonized)
    {
#ifdef RT_OS_WINDOWS
        VBoxServiceVerbose(2, "Starting service dispatcher ...\n");
        rcExit = VBoxServiceWinEnterCtrlDispatcher();
#else
        VBoxServiceVerbose(1, "Daemonizing...\n");
        rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */,
                             false /* fRespawn */, NULL /* pcRespawn */);
        if (RT_FAILURE(rc))
            return VBoxServiceError("Daemon failed: %Rrc\n", rc);
        /* in-child */
#endif
    }
#ifdef RT_OS_WINDOWS
    else
#endif
    {
        /*
         * Windows: We're running the service as a console application now. Start the
         *          services, enter the main thread's run loop and stop them again
         *          when it returns.
         *
         * POSIX:   This is used for both daemons and console runs. Start all services
         *          and return immediately.
         */
#ifdef RT_OS_WINDOWS
# ifndef RT_OS_NT4
        /* Install console control handler. */
        if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)VBoxServiceConsoleControlHandler, TRUE /* Add handler */))
        {
            VBoxServiceError("Unable to add console control handler, error=%ld\n", GetLastError());
            /* Just skip this error, not critical. */
        }
# endif /* !RT_OS_NT4 */
#endif /* RT_OS_WINDOWS */
        rc = VBoxServiceStartServices();
        rcExit = RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
        if (RT_SUCCESS(rc))
            VBoxServiceMainWait();
#ifdef RT_OS_WINDOWS
# ifndef RT_OS_NT4
        /* Uninstall console control handler. */
        if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)NULL, FALSE /* Remove handler */))
        {
            VBoxServiceError("Unable to remove console control handler, error=%ld\n", GetLastError());
            /* Just skip this error, not critical. */
        }
# endif /* !RT_OS_NT4 */
#else /* !RT_OS_WINDOWS */
        /* On Windows - since we're running as a console application - we already stopped all services
         * through the console control handler. So only do the stopping of services here on other platforms
         * where the break/shutdown/whatever signal was just received. */
        VBoxServiceStopServices();
#endif /* RT_OS_WINDOWS */
    }
    VBoxServiceReportStatus(VBoxGuestFacilityStatus_Terminated);

#ifdef RT_OS_WINDOWS
    /*
     * Cleanup mutex.
     */
    CloseHandle(hMutexAppRunning);
#endif

    VBoxServiceVerbose(0, "Ended.\n");

#ifdef DEBUG
    RTCritSectDelete(&g_csLog);
    //RTMemTrackerDumpAllToStdOut();
#endif

    VBoxServiceLogDestroy();

    return rcExit;
}
RTDECL(int) RTCrStoreCreateSnapshotById(PRTCRSTORE phStore, RTCRSTOREID enmStoreId, PRTERRINFO pErrInfo)
{
    AssertReturn(enmStoreId > RTCRSTOREID_INVALID && enmStoreId < RTCRSTOREID_END, VERR_INVALID_PARAMETER);

    /*
     * Create an empty in-memory store.
     */
    RTCRSTORE hStore;
    uint32_t cExpected = enmStoreId == RTCRSTOREID_SYSTEM_TRUSTED_CAS_AND_CERTIFICATES ? 256 : 0;
    int rc = RTCrStoreCreateInMem(&hStore, cExpected);
    if (RT_SUCCESS(rc))
    {
        *phStore = hStore;

        /*
         * Add system certificates if part of the given store ID.
         */
        bool fFound = false;
        rc = VINF_SUCCESS;
        if (enmStoreId == RTCRSTOREID_SYSTEM_TRUSTED_CAS_AND_CERTIFICATES)
        {
            for (uint32_t i = 0; i < RT_ELEMENTS(g_apszSystemPemFiles); i++)
                if (RTFileExists(g_apszSystemPemFiles[i]))
                {
                    fFound = true;
                    int rc2 = RTCrStoreCertAddFromFile(hStore,
                                                       RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR,
                                                       g_apszSystemPemFiles[i], pErrInfo);
                    if (RT_FAILURE(rc2))
                        rc = -rc2;
                }

            /*
             * If we didn't find any of the certificate collection files, go hunting
             * for directories containing PEM/CRT files with single certificates.
             */
            if (!fFound)
                for (uint32_t i = 0; i < RT_ELEMENTS(g_apszSystemPemDirs); i++)
                    if (RTDirExists(g_apszSystemPemDirs[i]))
                    {
                        static RTSTRTUPLE const s_aSuffixes[] =
                        {
                            { RT_STR_TUPLE(".crt") },
                            { RT_STR_TUPLE(".pem") },
                            { RT_STR_TUPLE(".PEM") },
                            { RT_STR_TUPLE(".CRT") },
                        };
                        fFound = true;
                        int rc2 = RTCrStoreCertAddFromDir(hStore,
                                                          RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR,
                                                          g_apszSystemPemDirs[i], &s_aSuffixes[0], RT_ELEMENTS(s_aSuffixes),
                                                          pErrInfo);
                        if (RT_FAILURE(rc2))
                            rc = -rc2;
                    }
        }
    }
    else
        RTErrInfoAdd(pErrInfo, rc, "  RTCrStoreCreateInMem failed");
    return rc;
}