VirtualBox

Changeset 39839 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jan 23, 2012 4:05:57 PM (13 years ago)
Author:
vboxsync
Message:

PDM: Initial driver chain transformation code (untested).

Location:
trunk/src/VBox/VMM
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PDM.cpp

    r39653 r39839  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    267267#include <iprt/assert.h>
    268268#include <iprt/alloc.h>
     269#include <iprt/ctype.h>
    269270#include <iprt/ldr.h>
    270271#include <iprt/path.h>
     
    23602361}
    23612362
     2363
     2364/**
     2365 * Checks that a PDMDRVREG::szName, PDMDEVREG::szName or PDMUSBREG::szName
     2366 * field contains only a limited set of ASCII characters.
     2367 *
     2368 * @returns true / false.
     2369 * @param   pszName             The name to validate.
     2370 */
     2371bool pdmR3IsValidName(const char *pszName)
     2372{
     2373    char ch;
     2374    while (   (ch = *pszName) != '\0'
     2375           && (   RT_C_IS_ALNUM(ch)
     2376               || ch == '-'
     2377               || ch == ' ' /** @todo disallow this! */
     2378               || ch == '_') )
     2379        pszName++;
     2380    return ch == '\0';
     2381}
     2382
  • trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp

    r39078 r39839  
    631631
    632632    AssertMsgReturn(    pReg->szName[0]
    633                     &&  strlen(pReg->szName) < sizeof(pReg->szName),
    634                     ("Invalid name '%s'\n", pReg->szName),
     633                    &&  strlen(pReg->szName) < sizeof(pReg->szName)
     634                    &&  pdmR3IsValidName(pReg->szName),
     635                    ("Invalid name '%.s'\n", sizeof(pReg->szName), pReg->szName),
    635636                    VERR_PDM_INVALID_DEVICE_REGISTRATION);
    636637    AssertMsgReturn(   !(pReg->fFlags & PDM_DEVREG_FLAGS_RC)
  • trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp

    r38878 r39839  
    270270    AssertReturn(pReg->szName[0], VERR_PDM_INVALID_DRIVER_REGISTRATION);
    271271    AssertMsgReturn(RTStrEnd(pReg->szName, sizeof(pReg->szName)),
    272                     (".*s\n", sizeof(pReg->szName), pReg->szName),
     272                    ("%.*s\n", sizeof(pReg->szName), pReg->szName),
     273                    VERR_PDM_INVALID_DRIVER_REGISTRATION);
     274    AssertMsgReturn(pdmR3IsValidName(pReg->szName), ("%.*s\n", pReg->szName),
    273275                    VERR_PDM_INVALID_DRIVER_REGISTRATION);
    274276    AssertMsgReturn(    !(pReg->fFlags & PDM_DRVREG_FLAGS_R0)
     
    370372
    371373/**
     374 * Transforms the driver chain as it's being instantiated.
     375 *
     376 * Worker for pdmR3DrvInstantiate.
     377 *
     378 * @returns VBox status code.
     379 * @param   pVM                 The VM handle.
     380 * @param   pDrvAbove           The driver above, NULL if top.
     381 * @param   pLun                The LUN.
     382 * @param   ppNode              The AttachedDriver node, replaced if any
     383 *                              morphing took place.
     384 */
     385static int pdmR3DrvMaybeTransformChain(PVM pVM, PPDMDRVINS pDrvAbove, PPDMLUN pLun, PCFGMNODE *ppNode)
     386{
     387    /*
     388     * The typical state of affairs is that there are no injections.
     389     */
     390    PCFGMNODE pCurTrans = CFGMR3GetFirstChild(CFGMR3GetChild(CFGMR3GetRoot(pVM), "PDM/DriverTransformations"));
     391    if (!pCurTrans)
     392        return VINF_SUCCESS;
     393
     394    /*
     395     * Gather the attributes used in the matching process.
     396     */
     397    const char *pszDevice = pLun->pDevIns->Internal.s.pDevR3->pReg->szName;
     398    char        szLun[32];
     399    RTStrPrintf(szLun, sizeof(szLun), "%u", pLun->iLun);
     400    const char *pszAbove  = pDrvAbove ? pDrvAbove->Internal.s.pDrv->pReg->szName : "<top>";
     401    char       *pszThisDrv;
     402    int rc = CFGMR3QueryStringAlloc(*ppNode, "Driver", &pszThisDrv);
     403    AssertMsgRCReturn(rc,  ("Query for string value of \"Driver\" -> %Rrc\n", rc),
     404                      rc == VERR_CFGM_VALUE_NOT_FOUND ? VERR_PDM_CFG_MISSING_DRIVER_NAME : rc);
     405
     406
     407    /*
     408     * Enumerate possible driver chain transformations.
     409     */
     410    for (; pCurTrans != NULL; pCurTrans = CFGMR3GetNextChild(pCurTrans))
     411    {
     412        /* Match against the driver multi pattern. */
     413        char *pszMultiPat;
     414        rc = CFGMR3QueryStringAllocDef(pCurTrans, "Driver", &pszMultiPat, "*");
     415        AssertLogRelRCReturn(rc, rc);
     416        bool fMatch = RTStrSimplePatternMultiMatch(pszMultiPat, RTSTR_MAX, pszDevice, RTSTR_MAX, NULL);
     417        MMR3HeapFree(pszMultiPat);
     418        if (!fMatch)
     419            continue;
     420
     421        /* Match against the lun multi pattern. */
     422        rc = CFGMR3QueryStringAllocDef(pCurTrans, "LUN", &pszMultiPat, "*");
     423        AssertLogRelRCReturn(rc, rc);
     424        fMatch = RTStrSimplePatternMultiMatch(pszMultiPat, RTSTR_MAX, szLun, RTSTR_MAX, NULL);
     425        MMR3HeapFree(pszMultiPat);
     426        if (!fMatch)
     427            continue;
     428
     429        /* Match against the below-driver multi pattern. */
     430        rc = CFGMR3QueryStringAllocDef(pCurTrans, "BelowDriver", &pszMultiPat, "*");
     431        AssertLogRelRCReturn(rc, rc);
     432        fMatch = RTStrSimplePatternMultiMatch(pszMultiPat, RTSTR_MAX, pszAbove, RTSTR_MAX, NULL);
     433        MMR3HeapFree(pszMultiPat);
     434        if (!fMatch)
     435            continue;
     436
     437        /* Match against the above-driver multi pattern. */
     438        /** @todo add some config to avoid infinie application of an
     439         * AboveDriver transformation. */
     440        rc = CFGMR3QueryStringAllocDef(pCurTrans, "AboveDriver", &pszMultiPat, "*");
     441        AssertLogRelRCReturn(rc, rc);
     442        fMatch = RTStrSimplePatternMultiMatch(pszMultiPat, RTSTR_MAX, pszThisDrv, RTSTR_MAX, NULL);
     443        MMR3HeapFree(pszMultiPat);
     444        if (!fMatch)
     445            continue;
     446
     447        /*
     448         * We've got a match! Now, what are we supposed to do?
     449         */
     450        char szAction[16];
     451        rc = CFGMR3QueryStringDef(pCurTrans, "Action", szAction, sizeof(szAction), "inject");
     452        AssertLogRelRCReturn(rc, rc);
     453        AssertLogRelMsgFailedReturn(("Action='%s', valid values are 'inject', 'replace' and 'remove'.\n",  szAction),
     454                                    VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION);
     455
     456        AssertLogRelMsgReturn(   !strcmp(szAction, "inject")
     457                              || !strcmp(szAction, "replace")
     458                              || !strcmp(szAction, "remove"),
     459                              ("Action='%s', valid values are 'inject', 'replace' and 'remove'.\n",  szAction),
     460                              VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION);
     461
     462        /* Get the attached driver to inject. */
     463        PCFGMNODE pTransAttDrv = NULL;
     464        if (!strcmp(szAction, "inject") || !strcmp(szAction, "replace"))
     465        {
     466            pTransAttDrv = CFGMR3GetChild(pCurTrans, "AttachedDriver");
     467            AssertLogRelMsgReturn(pTransAttDrv,
     468                                  ("An %s transformation requires an AttachedDriver child node!\n", szAction),
     469                                  VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION);
     470        }
     471
     472
     473        /*
     474         * Remove the node.
     475         */
     476        if (!strcmp(szAction, "remove"))
     477        {
     478            PCFGMNODE pBelowThis = CFGMR3GetChild(*ppNode, "AttachedDriver");
     479            if (pBelowThis)
     480            {
     481                PCFGMNODE pBelowThisCopy = CFGMR3DuplicateSubTree(pBelowThis);
     482                AssertLogRelReturn(pBelowThisCopy, VERR_NO_MEMORY);
     483
     484                rc = CFGMR3ReplaceSubTree(*ppNode, pBelowThisCopy);
     485                if (RT_FAILURE(rc))
     486                {
     487                    CFGMR3RemoveNode(pBelowThis);
     488                    AssertLogRelReturn(("rc=%Rrc\n", rc), rc);
     489                }
     490            }
     491            else
     492            {
     493                CFGMR3RemoveNode(*ppNode);
     494                *ppNode = NULL;
     495            }
     496        }
     497        /*
     498         * Replace the driver about to be instantiated.
     499         */
     500        else if (!strcmp(szAction, "replace"))
     501        {
     502            PCFGMNODE pTransCopy = CFGMR3DuplicateSubTree(pTransAttDrv);
     503            AssertLogRelBreakStmt(pTransCopy, rc = VERR_NO_MEMORY);
     504            rc = VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION;
     505
     506            PCFGMNODE pBelowThis = CFGMR3GetChild(*ppNode, "AttachedDriver");
     507            if (!pBelowThis)
     508                rc = VINF_SUCCESS;
     509            else
     510            {
     511                PCFGMNODE pBelowThisCopy = CFGMR3DuplicateSubTree(pBelowThis);
     512                if (pBelowThisCopy)
     513                {
     514                    rc = CFGMR3InsertSubTree(pTransCopy, "AttachedDriver", pBelowThisCopy, NULL);
     515                    AssertLogRelRC(rc);
     516                    if (RT_FAILURE(rc))
     517                        CFGMR3RemoveNode(pBelowThisCopy);
     518                }
     519            }
     520            if (RT_SUCCESS(rc))
     521                rc = CFGMR3ReplaceSubTree(*ppNode, pTransCopy);
     522            if (RT_FAILURE(rc))
     523                CFGMR3RemoveNode(pTransCopy);
     524        }
     525        /*
     526         * Inject a driver before the driver about to be instantiated.
     527         */
     528        else if (!strcmp(szAction, "inject"))
     529        {
     530            PCFGMNODE pTransCopy = CFGMR3DuplicateSubTree(pTransAttDrv);
     531            AssertLogRelBreakStmt(pTransCopy, rc = VERR_NO_MEMORY);
     532            rc = VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION;
     533
     534            PCFGMNODE pThisCopy = CFGMR3DuplicateSubTree(*ppNode);
     535            if (pThisCopy)
     536            {
     537                rc = CFGMR3InsertSubTree(pTransCopy, "AttachedDriver", pThisCopy, NULL);
     538                AssertLogRelRC(rc);
     539                if (RT_FAILURE(rc))
     540                    CFGMR3RemoveNode(pThisCopy);
     541            }
     542            if (RT_SUCCESS(rc))
     543                rc = CFGMR3ReplaceSubTree(*ppNode, pTransCopy);
     544            if (RT_FAILURE(rc))
     545                CFGMR3RemoveNode(pTransCopy);
     546        }
     547        else
     548            AssertFailed();
     549        break;
     550    }
     551
     552    return rc;
     553}
     554
     555
     556/**
    372557 * Instantiate a driver.
    373558 *
     
    397582
    398583    /*
     584     * Do driver chain injections
     585     */
     586    int rc = pdmR3DrvMaybeTransformChain(pVM, pDrvAbove, pLun, &pNode);
     587    if (RT_FAILURE(rc))
     588        return rc;
     589
     590    /*
    399591     * Find the driver.
    400592     */
    401593    char *pszName;
    402     int rc = CFGMR3QueryStringAlloc(pNode, "Driver", &pszName);
     594    rc = CFGMR3QueryStringAlloc(pNode, "Driver", &pszName);
    403595    if (RT_SUCCESS(rc))
    404596    {
  • trunk/src/VBox/VMM/VMMR3/PDMUsb.cpp

    r39078 r39839  
    222222                    VERR_PDM_UNKNOWN_USBREG_VERSION);
    223223    AssertMsgReturn(    pReg->szName[0]
    224                     &&  strlen(pReg->szName) < sizeof(pReg->szName),
    225                     ("Invalid name '%s'\n", pReg->szName),
     224                    &&  strlen(pReg->szName) < sizeof(pReg->szName)
     225                    &&  pdmR3IsValidName(pReg->szName),
     226                    ("Invalid name '%.s'\n", sizeof(pReg->szName), pReg->szName),
    226227                    VERR_PDM_INVALID_USB_REGISTRATION);
    227228    AssertMsgReturn(pReg->fFlags == 0, ("fFlags=%#x\n", pReg->fFlags), VERR_PDM_INVALID_USB_REGISTRATION);
  • trunk/src/VBox/VMM/include/PDMInternal.h

    r37836 r39839  
    11241124*******************************************************************************/
    11251125#ifdef IN_RING3
     1126bool        pdmR3IsValidName(const char *pszName);
     1127
    11261128int         pdmR3CritSectInitStats(PVM pVM);
    11271129void        pdmR3CritSectRelocate(PVM pVM);
     
    11931195
    11941196#endif
     1197
Note: See TracChangeset for help on using the changeset viewer.

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