HRESULT SystemProperties::getStorageControllerHotplugCapable(StorageControllerType_T aControllerType,
                                                             BOOL *aHotplugCapable)
{
    switch (aControllerType)
    {
        case StorageControllerType_IntelAhci:
        case StorageControllerType_USB:
            *aHotplugCapable = true;
            break;
        case StorageControllerType_LsiLogic:
        case StorageControllerType_LsiLogicSas:
        case StorageControllerType_BusLogic:
        case StorageControllerType_NVMe:
        case StorageControllerType_PIIX3:
        case StorageControllerType_PIIX4:
        case StorageControllerType_ICH6:
        case StorageControllerType_I82078:
            *aHotplugCapable = false;
            break;
        default:
            AssertMsgFailedReturn(("Invalid controller type %d\n", aControllerType), E_FAIL);
    }

    return S_OK;
}
int DnDHGSendDataMessage::currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
    if (!m_pNextPathMsg)
        return VERR_NO_DATA;

    /* Fill the data out of our current queued message. */
    int rc = m_pNextPathMsg->currentMessage(uMsg, cParms, paParms);
    /* Has this message more data to deliver? */
    if (!m_pNextPathMsg->isMessageWaiting())
    {
        delete m_pNextPathMsg;
        m_pNextPathMsg = NULL;
    }

    /* File data to send? */
    if (!m_pNextPathMsg)
    {
        if (m_uriList.isEmpty())
            return rc;
        /* Create new messages based on our internal path list. Currently
         * this could be directories or regular files. */
        PathEntry nextPath = m_uriList.first();
        if (RTFS_IS_DIRECTORY(nextPath.m_fMode))
            m_pNextPathMsg = new DnDHGSendDirPrivate(nextPath.m_strGuestPath, nextPath.m_fMode, nextPath.m_cbSize, &DnDHGSendDataMessage::progressCallback, this);
        else if (RTFS_IS_FILE(nextPath.m_fMode))
            m_pNextPathMsg = new DnDHGSendFilePrivate(nextPath.m_strHostPath, nextPath.m_strGuestPath, nextPath.m_fMode, nextPath.m_cbSize, &DnDHGSendDataMessage::progressCallback, this);
        else
            AssertMsgFailedReturn(("type '%d' is not supported for path '%s'", nextPath.m_fMode, nextPath.m_strHostPath.c_str()), VERR_NO_DATA);
        m_uriList.removeFirst();
    }
    return rc;
}
Exemple #3
0
/**
 * @interface_method_impl{DBGCCMDHLP,pfnVarFromDbgfAddr}
 */
static DECLCALLBACK(int) dbgcHlpVarFromDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGFADDRESS pAddress, PDBGCVAR pResult)
{
    AssertPtrReturn(pAddress, VERR_INVALID_POINTER);
    AssertReturn(DBGFADDRESS_IS_VALID(pAddress), VERR_INVALID_PARAMETER);
    AssertPtrReturn(pResult,  VERR_INVALID_POINTER);

    switch (pAddress->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK)
    {
        case DBGFADDRESS_FLAGS_FAR16:
        case DBGFADDRESS_FLAGS_FAR32:
        case DBGFADDRESS_FLAGS_FAR64:
            DBGCVAR_INIT_GC_FAR(pResult, pAddress->Sel, pAddress->off);
            break;

        case DBGFADDRESS_FLAGS_FLAT:
            DBGCVAR_INIT_GC_FLAT(pResult, pAddress->FlatPtr);
            break;

        case DBGFADDRESS_FLAGS_PHYS:
            DBGCVAR_INIT_GC_PHYS(pResult, pAddress->FlatPtr);
            break;

        default:
            DBGCVAR_INIT(pResult);
            AssertMsgFailedReturn(("%#x\n", pAddress->fFlags), VERR_INVALID_PARAMETER);
            break;
    }

    return VINF_SUCCESS;
}
Exemple #4
0
int DnDHGSendDataMessage::currentMessage(uint32_t uMsg,
                                         uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
    if (!m_pNextPathMsg)
        return VERR_NO_DATA;

    /* Fill the data out of our current queued message. */
    int rc = m_pNextPathMsg->currentMessage(uMsg, cParms, paParms);
    /* Has this message more data to deliver? */
    if (!m_pNextPathMsg->isMessageWaiting())
    {
        delete m_pNextPathMsg;
        m_pNextPathMsg = NULL;
    }

    /* File/directory data to send? */
    if (!m_pNextPathMsg)
    {
        if (m_lstURI.IsEmpty())
            return rc;

        /* Create new messages based on our internal path list. Currently
         * this could be directories or regular files. */
        const DnDURIObject &nextObj = m_lstURI.First();
        try
        {
            uint32_t fMode = nextObj.GetMode();
            LogFlowFunc(("Processing srcPath=%s, dstPath=%s, fMode=0x%x, cbSize=%RU32, fIsDir=%RTbool, fIsFile=%RTbool\n",
                         nextObj.GetSourcePath().c_str(), nextObj.GetDestPath().c_str(),
                         fMode, nextObj.GetSize(),
                         RTFS_IS_DIRECTORY(fMode), RTFS_IS_FILE(fMode)));

            if (RTFS_IS_DIRECTORY(fMode))
                m_pNextPathMsg = new DnDHGSendDirPrivate(nextObj,
                                                         &DnDHGSendDataMessage::progressCallback /* pfnProgressCallback */,
                                                         this /* pvProgressUser */);
            else if (RTFS_IS_FILE(fMode))
                m_pNextPathMsg = new DnDHGSendFilePrivate(nextObj,
                                                          &DnDHGSendDataMessage::progressCallback /* pfnProgressCallback */,
                                                          this /* pvProgressUser */);
            else
                AssertMsgFailedReturn(("fMode=0x%x is not supported for srcPath=%s, dstPath=%s\n",
                                       fMode, nextObj.GetSourcePath().c_str(), nextObj.GetDestPath().c_str()),
                                       VERR_NO_DATA);

            m_lstURI.RemoveFirst();
        }
        catch(std::bad_alloc &)
        {
            rc = VERR_NO_MEMORY;
        }
    }

    return rc;
}
KHLP_DECL(int) kHlpGetEnv(const char *pszVar, char *pszVal, KSIZE cchVal)
{
    int rc = RTEnvGetEx(RTENV_DEFAULT, pszVar, pszVal, cchVal, NULL);
    switch (rc)
    {
        case VINF_SUCCESS:              return 0;
        case VERR_ENV_VAR_NOT_FOUND:    return KERR_ENVVAR_NOT_FOUND;
        case VERR_BUFFER_OVERFLOW:      return KERR_BUFFER_OVERFLOW;
        default:                        AssertMsgFailedReturn(("%Rrc\n", rc), rc);
    }
}
Exemple #6
0
/**
 * EMT worker for DBGFR3BpClear().
 *
 * @returns VBox status code.
 * @param   pVM         Pointer to the VM.
 * @param   iBp         The id of the breakpoint which should be removed (cleared).
 * @thread  EMT
 * @internal
 */
static DECLCALLBACK(int) dbgfR3BpClear(PVM pVM, uint32_t iBp)
{
    /*
     * Validate input.
     */
    PDBGFBP pBp = dbgfR3BpGet(pVM, iBp);
    if (!pBp)
        return VERR_DBGF_BP_NOT_FOUND;

    /*
     * Disarm the breakpoint if it's enabled.
     */
    if (pBp->fEnabled)
    {
        pBp->fEnabled = false;
        int rc;
        switch (pBp->enmType)
        {
            case DBGFBPTYPE_REG:
                rc = dbgfR3BpRegDisarm(pVM, pBp);
                break;

            case DBGFBPTYPE_INT3:
                rc = dbgfR3BpInt3Disarm(pVM, pBp);
                break;

            case DBGFBPTYPE_REM:
#ifdef VBOX_WITH_REM
                rc = REMR3BreakpointClear(pVM, pBp->GCPtr);
#else
                rc = IEMBreakpointClear(pVM, pBp->GCPtr);
#endif
                break;

            default:
                AssertMsgFailedReturn(("Invalid enmType=%d!\n", pBp->enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE);
        }
        AssertRCReturn(rc, rc);
    }

    /*
     * Free the breakpoint.
     */
    dbgfR3BpFree(pVM, pBp);
    return VINF_SUCCESS;
}
Exemple #7
0
/**
 * EMT worker for DBGFR3BpEnable().
 *
 * @returns VBox status code.
 * @param   pVM         Pointer to the VM.
 * @param   iBp         The id of the breakpoint which should be enabled.
 * @thread  EMT
 * @internal
 */
static DECLCALLBACK(int) dbgfR3BpEnable(PVM pVM, uint32_t iBp)
{
    /*
     * Validate input.
     */
    PDBGFBP pBp = dbgfR3BpGet(pVM, iBp);
    if (!pBp)
        return VERR_DBGF_BP_NOT_FOUND;

    /*
     * Already enabled?
     */
    if (pBp->fEnabled)
        return VINF_DBGF_BP_ALREADY_ENABLED;

    /*
     * Remove the breakpoint.
     */
    int rc;
    pBp->fEnabled = true;
    switch (pBp->enmType)
    {
        case DBGFBPTYPE_REG:
            rc = dbgfR3BpRegArm(pVM, pBp);
            break;

        case DBGFBPTYPE_INT3:
            rc = dbgfR3BpInt3Arm(pVM, pBp);
            break;

        case DBGFBPTYPE_REM:
#ifdef VBOX_WITH_REM
            rc = REMR3BreakpointSet(pVM, pBp->GCPtr);
#else
            rc = IEMBreakpointSet(pVM, pBp->GCPtr);
#endif
            break;

        default:
            AssertMsgFailedReturn(("Invalid enmType=%d!\n", pBp->enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE);
    }
    if (RT_FAILURE(rc))
        pBp->fEnabled = false;

    return rc;
}
Exemple #8
0
RTDECL(int) RTDirOpenFiltered(PRTDIR *ppDir, const char *pszPath, RTDIRFILTER enmFilter, uint32_t fOpen)
{
    /*
     * Validate input.
     */
    AssertMsgReturn(VALID_PTR(ppDir), ("%p\n", ppDir), VERR_INVALID_POINTER);
    AssertMsgReturn(VALID_PTR(pszPath), ("%p\n", pszPath), VERR_INVALID_POINTER);
    AssertReturn(!(fOpen & ~RTDIROPEN_FLAGS_NO_SYMLINKS), VERR_INVALID_FLAGS);
    switch (enmFilter)
    {
        case RTDIRFILTER_UNIX:
        case RTDIRFILTER_UNIX_UPCASED:
            AssertMsgFailed(("%d is not implemented!\n", enmFilter));
            return VERR_NOT_IMPLEMENTED;
        case RTDIRFILTER_NONE:
        case RTDIRFILTER_WINNT:
            break;
        default:
            AssertMsgFailedReturn(("%d\n", enmFilter), VERR_INVALID_PARAMETER);
    }

    /*
     * Find the last component, i.e. where the filter criteria starts and the dir name ends.
     */
    const char *pszFilter;
    if (enmFilter == RTDIRFILTER_NONE)
        pszFilter = NULL;
    else
    {
        pszFilter = RTPathFilename(pszPath);
        if (!pszFilter) /* trailing slash => directory to read => no filter. */
            enmFilter = RTDIRFILTER_NONE;
    }

    /*
     * Call worker common with RTDirOpen which will verify the path, allocate
     * and initialize the handle, and finally call the backend.
     */
    int rc = rtDirOpenCommon(ppDir, pszPath, pszFilter, enmFilter);

    LogFlow(("RTDirOpenFiltered(%p:{%p}, %p:{%s}, %d): return %Rrc\n",
             ppDir, *ppDir, pszPath, pszPath, enmFilter, rc));
    return rc;
}
/**
 * EMT worker for DBGFR3BpDisable().
 *
 * @returns VBox status code.
 * @param   pVM         The VM handle.
 * @param   iBp         The id of the breakpoint which should be disabled.
 * @thread  EMT
 * @internal
 */
static DECLCALLBACK(int) dbgfR3BpDisable(PVM pVM, uint32_t iBp)
{
    /*
     * Validate input.
     */
    PDBGFBP pBp = dbgfR3BpGet(pVM, iBp);
    if (!pBp)
        return VERR_DBGF_BP_NOT_FOUND;

    /*
     * Already enabled?
     */
    if (!pBp->fEnabled)
        return VINF_DBGF_BP_ALREADY_DISABLED;

    /*
     * Remove the breakpoint.
     */
    pBp->fEnabled = false;
    int rc;
    switch (pBp->enmType)
    {
        case DBGFBPTYPE_REG:
            rc = dbgfR3BpRegDisarm(pVM, pBp);
            break;

        case DBGFBPTYPE_INT3:
            rc = dbgfR3BpInt3Disarm(pVM, pBp);
            break;

        case DBGFBPTYPE_REM:
            rc = REMR3BreakpointClear(pVM, pBp->GCPtr);
            break;

        default:
            AssertMsgFailedReturn(("Invalid enmType=%d!\n", pBp->enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE);
    }

    return rc;
}
Exemple #10
0
HRESULT USBController::getUSBStandard(USHORT *aUSBStandard)
{
    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);

    switch (m->bd->enmType)
    {
        case USBControllerType_OHCI:
            *aUSBStandard = 0x0101;
            break;
        case USBControllerType_EHCI:
            *aUSBStandard = 0x0200;
            break;
        case USBControllerType_XHCI:
            *aUSBStandard = 0x0200;
            break;
        default:
            AssertMsgFailedReturn(("Invalid controller type %d\n", m->bd->enmType),
                                  E_FAIL);
    }

    return S_OK;
}
Exemple #11
0
DECLHIDDEN(PVDSCRIPTASTCORE) vdScriptAstNodeAlloc(VDSCRIPTASTCLASS enmClass)
{
    size_t cbAlloc = 0;

    switch (enmClass)
    {
        case VDSCRIPTASTCLASS_FUNCTION:
            cbAlloc = sizeof(VDSCRIPTASTFN);
            break;
        case VDSCRIPTASTCLASS_FUNCTIONARG:
            cbAlloc = sizeof(VDSCRIPTASTFNARG);
            break;
        case VDSCRIPTASTCLASS_DECLARATION:
            cbAlloc = sizeof(VDSCRIPTASTDECL);
            break;
        case VDSCRIPTASTCLASS_STATEMENT:
            cbAlloc = sizeof(VDSCRIPTASTSTMT);
            break;
        case VDSCRIPTASTCLASS_EXPRESSION:
            cbAlloc = sizeof(VDSCRIPTASTEXPR);
            break;
        case VDSCRIPTASTCLASS_IDENTIFIER:
        case VDSCRIPTASTCLASS_INVALID:
        default:
            AssertMsgFailedReturn(("Invalid AST node class given %d\n", enmClass), NULL);
    }

    PVDSCRIPTASTCORE pAstNode = (PVDSCRIPTASTCORE)RTMemAllocZ(cbAlloc);
    if (pAstNode)
    {
        pAstNode->enmClass = enmClass;
        RTListInit(&pAstNode->ListNode);
    }

    return pAstNode;
}
Exemple #12
0
static int emR3ExecuteInstructionWorker(PVM pVM, PVMCPU pVCpu, int rcRC)
#endif
{
#ifdef LOG_ENABLED
    PCPUMCTX pCtx = pVCpu->em.s.pCtx;
#endif
    int      rc;
    NOREF(rcRC);

    /*
     *
     * The simple solution is to use the recompiler.
     * The better solution is to disassemble the current instruction and
     * try handle as many as possible without using REM.
     *
     */

#ifdef LOG_ENABLED
    /*
     * Disassemble the instruction if requested.
     */
    if (pszPrefix)
    {
        DBGFR3InfoLog(pVM, "cpumguest", pszPrefix);
        DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix);
    }
#endif /* LOG_ENABLED */

#if 0
    /* Try our own instruction emulator before falling back to the recompiler. */
    DISCPUSTATE Cpu;
    rc = CPUMR3DisasmInstrCPU(pVM, pVCpu, pCtx, pCtx->rip, &Cpu, "GEN EMU");
    if (RT_SUCCESS(rc))
    {
        switch (Cpu.pCurInstr->uOpcode)
        {
        /* @todo we can do more now */
        case OP_MOV:
        case OP_AND:
        case OP_OR:
        case OP_XOR:
        case OP_POP:
        case OP_INC:
        case OP_DEC:
        case OP_XCHG:
            STAM_PROFILE_START(&pVCpu->em.s.StatMiscEmu, a);
            rc = EMInterpretInstructionCpuUpdtPC(pVM, pVCpu, &Cpu, CPUMCTX2CORE(pCtx), 0);
            if (RT_SUCCESS(rc))
            {
#ifdef EM_NOTIFY_HWACCM
                if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HWACC)
                    HWACCMR3NotifyEmulated(pVCpu);
#endif
                STAM_PROFILE_STOP(&pVCpu->em.s.StatMiscEmu, a);
                return rc;
            }
            if (rc != VERR_EM_INTERPRETER)
                AssertMsgFailedReturn(("rc=%Rrc\n", rc), rc);
            STAM_PROFILE_STOP(&pVCpu->em.s.StatMiscEmu, a);
            break;
        }
    }
#endif /* 0 */
    STAM_PROFILE_START(&pVCpu->em.s.StatREMEmu, a);
    Log(("EMINS: %04x:%RGv RSP=%RGv\n", pCtx->cs.Sel, (RTGCPTR)pCtx->rip, (RTGCPTR)pCtx->rsp));
#ifdef VBOX_WITH_REM
    EMRemLock(pVM);
    /* Flush the recompiler TLB if the VCPU has changed. */
    if (pVM->em.s.idLastRemCpu != pVCpu->idCpu)
        CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_ALL);
    pVM->em.s.idLastRemCpu = pVCpu->idCpu;

    rc = REMR3EmulateInstruction(pVM, pVCpu);
    EMRemUnlock(pVM);
#else
    rc = VBOXSTRICTRC_TODO(IEMExecOne(pVCpu)); NOREF(pVM);
#endif
    STAM_PROFILE_STOP(&pVCpu->em.s.StatREMEmu, a);

#ifdef EM_NOTIFY_HWACCM
    if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HWACC)
        HWACCMR3NotifyEmulated(pVCpu);
#endif
    return rc;
}
Exemple #13
0
/**
 * Display several info items.
 *
 * This is intended used by the fatal error dump only.
 *
 * @returns
 * @param   pVM             Pointer to the VM.
 * @param   pszIncludePat   Simple string pattern of info items to include.
 * @param   pszExcludePat   Simple string pattern of info items to exclude.
 * @param   pszSepFmt       Item separator format string.  The item name will be
 *                          given as parameter.
 * @param   pHlp            The output helper functions.  If NULL the logger
 *                          will be used.
 *
 * @threads EMT
 */
VMMR3DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat, const char *pszSepFmt,
                               PCDBGFINFOHLP pHlp)
{
    /*
     * Validate input.
     */
    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    AssertPtrReturn(pszIncludePat, VERR_INVALID_POINTER);
    AssertPtrReturn(pszExcludePat, VERR_INVALID_POINTER);
    if (pHlp)
    {
        AssertPtrReturn(pHlp->pfnPrintf, VERR_INVALID_POINTER);
        AssertPtrReturn(pHlp->pfnPrintfV, VERR_INVALID_POINTER);
    }
    else
        pHlp = &g_dbgfR3InfoLogHlp;

    size_t const cchIncludePat = strlen(pszIncludePat);
    size_t const cchExcludePat = strlen(pszExcludePat);
    const char *pszArgs = "";

    /*
     * Enumerate the info handlers and call the ones matching.
     * Note! We won't leave the critical section here...
     */
    int rc = RTCritSectEnter(&pVM->dbgf.s.InfoCritSect);
    AssertRC(rc);
    rc = VWRN_NOT_FOUND;
    for (PDBGFINFO pInfo = pVM->dbgf.s.pInfoFirst; pInfo; pInfo = pInfo->pNext)
    {
        if (   RTStrSimplePatternMultiMatch(pszIncludePat, cchIncludePat, pInfo->szName, pInfo->cchName, NULL)
            && !RTStrSimplePatternMultiMatch(pszExcludePat, cchExcludePat, pInfo->szName, pInfo->cchName, NULL))
        {
            pHlp->pfnPrintf(pHlp, pszSepFmt, pInfo->szName);
            rc = VINF_SUCCESS;
            switch (pInfo->enmType)
            {
                case DBGFINFOTYPE_DEV:
                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                        rc = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)pInfo->u.Dev.pfnHandler, 3, pInfo->u.Dev.pDevIns, pHlp, pszArgs);
                    else
                        pInfo->u.Dev.pfnHandler(pInfo->u.Dev.pDevIns, pHlp, pszArgs);
                    break;

                case DBGFINFOTYPE_DRV:
                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                        rc = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)pInfo->u.Drv.pfnHandler, 3, pInfo->u.Drv.pDrvIns, pHlp, pszArgs);
                    else
                        pInfo->u.Drv.pfnHandler(pInfo->u.Drv.pDrvIns, pHlp, pszArgs);
                    break;

                case DBGFINFOTYPE_INT:
                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                        rc = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)pInfo->u.Int.pfnHandler, 3, pVM, pHlp, pszArgs);
                    else
                        pInfo->u.Int.pfnHandler(pVM, pHlp, pszArgs);
                    break;

                case DBGFINFOTYPE_EXT:
                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                        rc = VMR3ReqCallVoidWait(pVM, VMCPUID_ANY, (PFNRT)pInfo->u.Ext.pfnHandler, 3, pInfo->u.Ext.pvUser, pHlp, pszArgs);
                    else
                        pInfo->u.Ext.pfnHandler(pInfo->u.Ext.pvUser, pHlp, pszArgs);
                    break;

                default:
                    AssertMsgFailedReturn(("Invalid info type enmType=%d\n", pInfo->enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE);
            }
        }
    }
    int rc2 = RTCritSectLeave(&pVM->dbgf.s.InfoCritSect);
    AssertRC(rc2);

    return rc;
}
Exemple #14
0
/**
 * Worker for DBGFR3Info and DBGFR3InfoEx.
 *
 * @returns VBox status code.
 * @param   pVM                 Pointer to the VM.
 * @param   idCpu               Which CPU to run EMT bound handlers on.
 *                              VMCPUID_ANY or a valid CPU ID.
 * @param   pszName             What to dump.
 * @param   pszArgs             Arguments, optional.
 * @param   pHlp                Output helper, optional.
 */
static DECLCALLBACK(int) dbgfR3Info(PVM pVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp)
{
    /*
     * Validate input.
     */
    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
    if (pHlp)
    {
        if (    !pHlp->pfnPrintf
            ||  !pHlp->pfnPrintfV)
        {
            AssertMsgFailed(("A pHlp member is missing!\n"));
            return VERR_INVALID_PARAMETER;
        }
    }
    else
        pHlp = &g_dbgfR3InfoLogHlp;

    /*
     * Find the info handler.
     */
    size_t cchName = strlen(pszName);
    int rc = RTCritSectEnter(&pVM->dbgf.s.InfoCritSect);
    AssertRC(rc);
    PDBGFINFO pInfo = pVM->dbgf.s.pInfoFirst;
    for (; pInfo; pInfo = pInfo->pNext)
        if (    pInfo->cchName == cchName
            &&  !memcmp(pInfo->szName, pszName, cchName))
            break;
    if (pInfo)
    {
        /*
         * Found it.
         *      Make a copy of it on the stack so we can leave the crit sect.
         *      Switch on the type and invoke the handler.
         */
        DBGFINFO Info = *pInfo;
        rc = RTCritSectLeave(&pVM->dbgf.s.InfoCritSect);
        AssertRC(rc);
        rc = VINF_SUCCESS;
        switch (Info.enmType)
        {
            case DBGFINFOTYPE_DEV:
                if (Info.fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                    rc = VMR3ReqCallVoidWait(pVM, idCpu, (PFNRT)Info.u.Dev.pfnHandler, 3, Info.u.Dev.pDevIns, pHlp, pszArgs);
                else
                    Info.u.Dev.pfnHandler(Info.u.Dev.pDevIns, pHlp, pszArgs);
                break;

            case DBGFINFOTYPE_DRV:
                if (Info.fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                    rc = VMR3ReqCallVoidWait(pVM, idCpu, (PFNRT)Info.u.Drv.pfnHandler, 3, Info.u.Drv.pDrvIns, pHlp, pszArgs);
                else
                    Info.u.Drv.pfnHandler(Info.u.Drv.pDrvIns, pHlp, pszArgs);
                break;

            case DBGFINFOTYPE_INT:
                if (Info.fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                    rc = VMR3ReqCallVoidWait(pVM, idCpu, (PFNRT)Info.u.Int.pfnHandler, 3, pVM, pHlp, pszArgs);
                else
                    Info.u.Int.pfnHandler(pVM, pHlp, pszArgs);
                break;

            case DBGFINFOTYPE_EXT:
                if (Info.fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
                    rc = VMR3ReqCallVoidWait(pVM, idCpu, (PFNRT)Info.u.Ext.pfnHandler, 3, Info.u.Ext.pvUser, pHlp, pszArgs);
                else
                    Info.u.Ext.pfnHandler(Info.u.Ext.pvUser, pHlp, pszArgs);
                break;

            default:
                AssertMsgFailedReturn(("Invalid info type enmType=%d\n", Info.enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE);
        }
    }
    else
    {
        rc = RTCritSectLeave(&pVM->dbgf.s.InfoCritSect);
        AssertRC(rc);
        rc = VERR_FILE_NOT_FOUND;
    }
    return rc;
}
Exemple #15
0
RTDECL(int) RTPathAbs(const char *pszPath, char *pszAbsPath, size_t cchAbsPath)
{
    int rc;

    /*
     * Validation.
     */
    AssertPtr(pszAbsPath);
    AssertPtr(pszPath);
    if (RT_UNLIKELY(!*pszPath))
        return VERR_INVALID_PARAMETER;

    /*
     * Make a clean working copy of the input.
     */
    size_t cchPath = strlen(pszPath);
    if (cchPath > PATH_MAX)
    {
        LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG));
        return VERR_FILENAME_TOO_LONG;
    }

    char szTmpPath[PATH_MAX + 1];
    memcpy(szTmpPath, pszPath, cchPath + 1);
    size_t cchTmpPath = fsCleanPath(szTmpPath);

    /*
     * Handle "." specially (fsCleanPath does).
     */
    if (szTmpPath[0] == '.' && !szTmpPath[1])
        return RTPathGetCurrent(pszAbsPath, cchAbsPath);

    /*
     * Do we have a root slash?
     */
    char *pszCur = szTmpPath;
#ifdef HAVE_DRIVE
    if (pszCur[0] && RTPATH_IS_VOLSEP(pszCur[1]) && pszCur[2] == '/')
        pszCur += 3;
# ifdef HAVE_UNC
    else if (pszCur[0] == '/' && pszCur[1] == '/')
        pszCur += 2;
# endif
#else  /* !HAVE_DRIVE */
    if (pszCur[0] == '/')
        pszCur += 1;
#endif /* !HAVE_DRIVE */
    else
    {
        /*
         * No, prepend the current directory to the relative path.
         */
        char szCurDir[RTPATH_MAX];
        rc = RTPathGetCurrent(szCurDir, sizeof(szCurDir));
        AssertRCReturn(rc, rc);

        size_t cchCurDir = fsCleanPath(szCurDir); /* paranoia */
        if (cchCurDir + cchTmpPath + 1 > PATH_MAX)
        {
            LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG));
            return VERR_FILENAME_TOO_LONG;
        }

        memmove(szTmpPath + cchCurDir + 1, szTmpPath, cchTmpPath + 1);
        memcpy(szTmpPath, szCurDir, cchCurDir);
        szTmpPath[cchCurDir] = '/';


#ifdef HAVE_DRIVE
        if (pszCur[0] && RTPATH_IS_VOLSEP(pszCur[1]) && pszCur[2] == '/')
            pszCur += 3;
# ifdef HAVE_UNC
        else if (pszCur[0] == '/' && pszCur[1] == '/')
            pszCur += 2;
# endif
#else
        if (pszCur[0] == '/')
            pszCur += 1;
#endif
        else
            AssertMsgFailedReturn(("pszCur=%s\n", pszCur), VERR_INTERNAL_ERROR);
    }

    char *pszTop = pszCur;

    /*
     * Get rid of double dot path components by evaluating them.
     */
    for (;;)
    {
        if (   pszCur[0] == '.'
            && pszCur[1] == '.'
            && (!pszCur[2] || pszCur[2] == '/'))
        {
            /* rewind to the previous component if any */
            char *pszPrev = pszCur - 1;
            if (pszPrev > pszTop)
                while (*--pszPrev != '/')
                    ;

            AssertMsg(*pszPrev == '/', ("szTmpPath={%s}, pszPrev=+%u\n", szTmpPath, pszPrev - szTmpPath));
            memmove(pszPrev, pszCur + 2, strlen(pszCur + 2) + 1);

            pszCur = pszPrev;
        }
        else
        {
            /* advance to end of component. */
            while (*pszCur && *pszCur != '/')
                pszCur++;
        }

        if (!*pszCur)
            break;

        /* skip the slash */
        ++pszCur;
    }

    if (pszCur < pszTop)
    {
        /*
         * We overwrote the root slash with '\0', restore it.
         */
        *pszCur++ = '/';
        *pszCur = '\0';
    }
    else if (pszCur > pszTop && pszCur[-1] == '/')
    {
        /*
         * Extra trailing slash in a non-root path, remove it.
         * (A bit questionable...)
         */
        *--pszCur = '\0';
    }

    /*
     * Copy the result to the user buffer.
     */
    cchTmpPath = pszCur - szTmpPath;
    if (cchTmpPath < cchAbsPath)
    {
        memcpy(pszAbsPath, szTmpPath, cchTmpPath + 1);
        rc = VINF_SUCCESS;
    }
    else
        rc = VERR_BUFFER_OVERFLOW;

    LogFlow(("RTPathAbs(%p:{%s}, %p:{%s}, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath,
             RT_SUCCESS(rc) ? pszAbsPath : "<failed>", cchAbsPath, rc));
    return rc;
}
RTR3DECL(int)   RTProcCreateEx(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags,
                               PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr, const char *pszAsUser,
                               const char *pszPassword, PRTPROCESS phProcess)
{
    int rc;

    /*
     * Input validation
     */
    AssertPtrReturn(pszExec, VERR_INVALID_POINTER);
    AssertReturn(*pszExec, VERR_INVALID_PARAMETER);
    AssertReturn(!(fFlags & ~RTPROC_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
    AssertReturn(!(fFlags & RTPROC_FLAGS_DETACHED) || !phProcess, VERR_INVALID_PARAMETER);
    AssertReturn(hEnv != NIL_RTENV, VERR_INVALID_PARAMETER);
    AssertPtrReturn(papszArgs, VERR_INVALID_PARAMETER);
    AssertPtrNullReturn(pszAsUser, VERR_INVALID_POINTER);
    AssertReturn(!pszAsUser || *pszAsUser, VERR_INVALID_PARAMETER);
    AssertReturn(!pszPassword || pszAsUser, VERR_INVALID_PARAMETER);
    AssertPtrNullReturn(pszPassword, VERR_INVALID_POINTER);
#if defined(RT_OS_OS2)
    if (fFlags & RTPROC_FLAGS_DETACHED)
        return VERR_PROC_DETACH_NOT_SUPPORTED;
#endif

    /*
     * Get the file descriptors for the handles we've been passed.
     */
    PCRTHANDLE  paHandles[3] = { phStdIn, phStdOut, phStdErr };
    int         aStdFds[3]   = {      -1,       -1,       -1 };
    for (int i = 0; i < 3; i++)
    {
        if (paHandles[i])
        {
            AssertPtrReturn(paHandles[i], VERR_INVALID_POINTER);
            switch (paHandles[i]->enmType)
            {
                case RTHANDLETYPE_FILE:
                    aStdFds[i] = paHandles[i]->u.hFile != NIL_RTFILE
                               ? (int)RTFileToNative(paHandles[i]->u.hFile)
                               : -2 /* close it */;
                    break;

                case RTHANDLETYPE_PIPE:
                    aStdFds[i] = paHandles[i]->u.hPipe != NIL_RTPIPE
                               ? (int)RTPipeToNative(paHandles[i]->u.hPipe)
                               : -2 /* close it */;
                    break;

                case RTHANDLETYPE_SOCKET:
                    aStdFds[i] = paHandles[i]->u.hSocket != NIL_RTSOCKET
                               ? (int)RTSocketToNative(paHandles[i]->u.hSocket)
                               : -2 /* close it */;
                    break;

                default:
                    AssertMsgFailedReturn(("%d: %d\n", i, paHandles[i]->enmType), VERR_INVALID_PARAMETER);
            }
            /** @todo check the close-on-execness of these handles?  */
        }
    }

    for (int i = 0; i < 3; i++)
        if (aStdFds[i] == i)
            aStdFds[i] = -1;

    for (int i = 0; i < 3; i++)
        AssertMsgReturn(aStdFds[i] < 0 || aStdFds[i] > i,
                        ("%i := %i not possible because we're lazy\n", i, aStdFds[i]),
                        VERR_NOT_SUPPORTED);

    /*
     * Resolve the user id if specified.
     */
    uid_t uid = ~(uid_t)0;
    gid_t gid = ~(gid_t)0;
    if (pszAsUser)
    {
        rc = rtCheckCredentials(pszAsUser, pszPassword, &gid, &uid);
        if (RT_FAILURE(rc))
            return rc;
    }

    /*
     * Create the child environment if either RTPROC_FLAGS_PROFILE or
     * RTPROC_FLAGS_ENV_CHANGE_RECORD are in effect.
     */
    RTENV hEnvToUse = hEnv;
    if (   (fFlags & (RTPROC_FLAGS_ENV_CHANGE_RECORD | RTPROC_FLAGS_PROFILE))
        && (   (fFlags & RTPROC_FLAGS_ENV_CHANGE_RECORD)
            || hEnv == RTENV_DEFAULT) )
    {
        if (fFlags & RTPROC_FLAGS_PROFILE)
            rc = rtProcPosixCreateProfileEnv(&hEnvToUse, pszAsUser);
        else
            rc = RTEnvClone(&hEnvToUse, RTENV_DEFAULT);
        if (RT_SUCCESS(rc))
        {
            if ((fFlags & RTPROC_FLAGS_ENV_CHANGE_RECORD) && hEnv != RTENV_DEFAULT)
                rc = RTEnvApplyChanges(hEnvToUse, hEnv);
            if (RT_FAILURE(rc))
                RTEnvDestroy(hEnvToUse);
        }
        if (RT_FAILURE(rc))
            return rc;
    }

    /*
     * Check for execute access to the file.
     */
    char szRealExec[RTPATH_MAX];
    if (access(pszExec, X_OK))
    {
        rc = errno;
        if (   !(fFlags & RTPROC_FLAGS_SEARCH_PATH)
            || rc != ENOENT
            || RTPathHavePath(pszExec) )
            rc = RTErrConvertFromErrno(rc);
        else
        {
            /* search */
            char *pszPath = RTEnvDupEx(hEnvToUse, "PATH");
            rc = RTPathTraverseList(pszPath, ':', rtPathFindExec, (void *)pszExec, &szRealExec[0]);
            RTStrFree(pszPath);
            if (RT_SUCCESS(rc))
                pszExec = szRealExec;
            else
                rc = rc == VERR_END_OF_STRING ? VERR_FILE_NOT_FOUND : rc;
        }

        if (RT_FAILURE(rc))
            return rtProcPosixCreateReturn(rc, hEnvToUse, hEnv);
    }

    pid_t pid = -1;
    const char * const *papszEnv = RTEnvGetExecEnvP(hEnvToUse);
    AssertPtrReturn(papszEnv, rtProcPosixCreateReturn(VERR_INVALID_HANDLE, hEnvToUse, hEnv));


    /*
     * Take care of detaching the process.
     *
     * HACK ALERT! Put the process into a new process group with pgid = pid
     * to make sure it differs from that of the parent process to ensure that
     * the IPRT waitpid call doesn't race anyone (read XPCOM) doing group wide
     * waits. setsid() includes the setpgid() functionality.
     * 2010-10-11 XPCOM no longer waits for anything, but it cannot hurt.
     */
#ifndef RT_OS_OS2
    if (fFlags & RTPROC_FLAGS_DETACHED)
    {
# ifdef RT_OS_SOLARIS
        int templateFd = -1;
        if (!(fFlags & RTPROC_FLAGS_SAME_CONTRACT))
        {
            templateFd = rtSolarisContractPreFork();
            if (templateFd == -1)
                return rtProcPosixCreateReturn(VERR_OPEN_FAILED, hEnvToUse, hEnv);
        }
# endif /* RT_OS_SOLARIS */
        pid = fork();
        if (!pid)
        {
# ifdef RT_OS_SOLARIS
            if (!(fFlags & RTPROC_FLAGS_SAME_CONTRACT))
                rtSolarisContractPostForkChild(templateFd);
# endif
            setsid(); /* see comment above */

            pid = -1;
            /* Child falls through to the actual spawn code below. */
        }
        else
        {
# ifdef RT_OS_SOLARIS
            if (!(fFlags & RTPROC_FLAGS_SAME_CONTRACT))
                rtSolarisContractPostForkParent(templateFd, pid);
# endif
            if (pid > 0)
            {
                /* Must wait for the temporary process to avoid a zombie. */
                int status = 0;
                pid_t pidChild = 0;

                /* Restart if we get interrupted. */
                do
                {
                    pidChild = waitpid(pid, &status, 0);
                } while (   pidChild == -1
                         && errno == EINTR);

                /* Assume that something wasn't found. No detailed info. */
                if (status)
                    return rtProcPosixCreateReturn(VERR_PROCESS_NOT_FOUND, hEnvToUse, hEnv);
                if (phProcess)
                    *phProcess = 0;
                return rtProcPosixCreateReturn(VINF_SUCCESS, hEnvToUse, hEnv);
            }
            return rtProcPosixCreateReturn(RTErrConvertFromErrno(errno), hEnvToUse, hEnv);
        }
    }
#endif

    /*
     * Spawn the child.
     *
     * Any spawn code MUST not execute any atexit functions if it is for a
     * detached process. It would lead to running the atexit functions which
     * make only sense for the parent. libORBit e.g. gets confused by multiple
     * execution. Remember, there was only a fork() so far, and until exec()
     * is successfully run there is nothing which would prevent doing anything
     * silly with the (duplicated) file descriptors.
     */
#ifdef HAVE_POSIX_SPAWN
    /** @todo OS/2: implement DETACHED (BACKGROUND stuff), see VbglR3Daemonize.  */
    if (   uid == ~(uid_t)0
        && gid == ~(gid_t)0)
    {
        /* Spawn attributes. */
        posix_spawnattr_t Attr;
        rc = posix_spawnattr_init(&Attr);
        if (!rc)
        {
            /* Indicate that process group and signal mask are to be changed,
               and that the child should use default signal actions. */
            rc = posix_spawnattr_setflags(&Attr, POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF);
            Assert(rc == 0);

            /* The child starts in its own process group. */
            if (!rc)
            {
                rc = posix_spawnattr_setpgroup(&Attr, 0 /* pg == child pid */);
                Assert(rc == 0);
            }

            /* Unmask all signals. */
            if (!rc)
            {
                sigset_t SigMask;
                sigemptyset(&SigMask);
                rc = posix_spawnattr_setsigmask(&Attr, &SigMask); Assert(rc == 0);
            }

            /* File changes. */
            posix_spawn_file_actions_t  FileActions;
            posix_spawn_file_actions_t *pFileActions = NULL;
            if ((aStdFds[0] != -1 || aStdFds[1] != -1 || aStdFds[2] != -1) && !rc)
            {
                rc = posix_spawn_file_actions_init(&FileActions);
                if (!rc)
                {
                    pFileActions = &FileActions;
                    for (int i = 0; i < 3; i++)
                    {
                        int fd = aStdFds[i];
                        if (fd == -2)
                            rc = posix_spawn_file_actions_addclose(&FileActions, i);
                        else if (fd >= 0 && fd != i)
                        {
                            rc = posix_spawn_file_actions_adddup2(&FileActions, fd, i);
                            if (!rc)
                            {
                                for (int j = i + 1; j < 3; j++)
                                    if (aStdFds[j] == fd)
                                    {
                                        fd = -1;
                                        break;
                                    }
                                if (fd >= 0)
                                    rc = posix_spawn_file_actions_addclose(&FileActions, fd);
                            }
                        }
                        if (rc)
                            break;
                    }
                }
            }

            if (!rc)
                rc = posix_spawn(&pid, pszExec, pFileActions, &Attr, (char * const *)papszArgs,
                                 (char * const *)papszEnv);

            /* cleanup */
            int rc2 = posix_spawnattr_destroy(&Attr); Assert(rc2 == 0); NOREF(rc2);
            if (pFileActions)
            {
                rc2 = posix_spawn_file_actions_destroy(pFileActions);
                Assert(rc2 == 0);
            }

            /* return on success.*/
            if (!rc)
            {
                /* For a detached process this happens in the temp process, so
                 * it's not worth doing anything as this process must exit. */
                if (fFlags & RTPROC_FLAGS_DETACHED)
                    _Exit(0);
                if (phProcess)
                    *phProcess = pid;
                return rtProcPosixCreateReturn(VINF_SUCCESS, hEnvToUse, hEnv);
            }
        }
        /* For a detached process this happens in the temp process, so
         * it's not worth doing anything as this process must exit. */
        if (fFlags & RTPROC_FLAGS_DETACHED)
            _Exit(124);
    }
    else
#endif
    {
#ifdef RT_OS_SOLARIS
        int templateFd = -1;
        if (!(fFlags & RTPROC_FLAGS_SAME_CONTRACT))
        {
            templateFd = rtSolarisContractPreFork();
            if (templateFd == -1)
                return rtProcPosixCreateReturn(VERR_OPEN_FAILED, hEnvToUse, hEnv);
        }
#endif /* RT_OS_SOLARIS */
        pid = fork();
        if (!pid)
        {
#ifdef RT_OS_SOLARIS
            if (!(fFlags & RTPROC_FLAGS_SAME_CONTRACT))
                rtSolarisContractPostForkChild(templateFd);
#endif /* RT_OS_SOLARIS */
            if (!(fFlags & RTPROC_FLAGS_DETACHED))
                setpgid(0, 0); /* see comment above */

            /*
             * Change group and user if requested.
             */
#if 1 /** @todo This needs more work, see suplib/hardening. */
            if (pszAsUser)
            {
                int ret = initgroups(pszAsUser, gid);
                if (ret)
                {
                    if (fFlags & RTPROC_FLAGS_DETACHED)
                        _Exit(126);
                    else
                        exit(126);
                }
            }
            if (gid != ~(gid_t)0)
            {
                if (setgid(gid))
                {
                    if (fFlags & RTPROC_FLAGS_DETACHED)
                        _Exit(126);
                    else
                        exit(126);
                }
            }

            if (uid != ~(uid_t)0)
            {
                if (setuid(uid))
                {
                    if (fFlags & RTPROC_FLAGS_DETACHED)
                        _Exit(126);
                    else
                        exit(126);
                }
            }
#endif

            /*
             * Some final profile environment tweaks, if running as user.
             */
            if (   (fFlags & RTPROC_FLAGS_PROFILE)
                && pszAsUser
                && (   (fFlags & RTPROC_FLAGS_ENV_CHANGE_RECORD)
                    || hEnv == RTENV_DEFAULT) )
            {
                rc = rtProcPosixAdjustProfileEnvFromChild(hEnvToUse, fFlags, hEnv);
                papszEnv = RTEnvGetExecEnvP(hEnvToUse);
                if (RT_FAILURE(rc) || !papszEnv)
                {
                    if (fFlags & RTPROC_FLAGS_DETACHED)
                        _Exit(126);
                    else
                        exit(126);
                }
            }

            /*
             * Unset the signal mask.
             */
            sigset_t SigMask;
            sigemptyset(&SigMask);
            rc = sigprocmask(SIG_SETMASK, &SigMask, NULL);
            Assert(rc == 0);

            /*
             * Apply changes to the standard file descriptor and stuff.
             */
            for (int i = 0; i < 3; i++)
            {
                int fd = aStdFds[i];
                if (fd == -2)
                    close(i);
                else if (fd >= 0)
                {
                    int rc2 = dup2(fd, i);
                    if (rc2 != i)
                    {
                        if (fFlags & RTPROC_FLAGS_DETACHED)
                            _Exit(125);
                        else
                            exit(125);
                    }
                    for (int j = i + 1; j < 3; j++)
                        if (aStdFds[j] == fd)
                        {
                            fd = -1;
                            break;
                        }
                    if (fd >= 0)
                        close(fd);
                }
            }

            /*
             * Finally, execute the requested program.
             */
            rc = execve(pszExec, (char * const *)papszArgs, (char * const *)papszEnv);
            if (errno == ENOEXEC)
            {
                /* This can happen when trying to start a shell script without the magic #!/bin/sh */
                RTAssertMsg2Weak("Cannot execute this binary format!\n");
            }
            else
                RTAssertMsg2Weak("execve returns %d errno=%d\n", rc, errno);
            RTAssertReleasePanic();
            if (fFlags & RTPROC_FLAGS_DETACHED)
                _Exit(127);
            else
                exit(127);
        }
#ifdef RT_OS_SOLARIS
        if (!(fFlags & RTPROC_FLAGS_SAME_CONTRACT))
            rtSolarisContractPostForkParent(templateFd, pid);
#endif /* RT_OS_SOLARIS */
        if (pid > 0)
        {
            /* For a detached process this happens in the temp process, so
             * it's not worth doing anything as this process must exit. */
            if (fFlags & RTPROC_FLAGS_DETACHED)
                _Exit(0);
            if (phProcess)
                *phProcess = pid;
            return rtProcPosixCreateReturn(VINF_SUCCESS, hEnvToUse, hEnv);
        }
        /* For a detached process this happens in the temp process, so
         * it's not worth doing anything as this process must exit. */
        if (fFlags & RTPROC_FLAGS_DETACHED)
            _Exit(124);
        return rtProcPosixCreateReturn(RTErrConvertFromErrno(errno), hEnvToUse, hEnv);
    }

    return rtProcPosixCreateReturn(VERR_NOT_IMPLEMENTED, hEnvToUse, hEnv);
}
Exemple #17
0
RTDECL(int) RTPowerNotificationRegister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser)
{
    PRTPOWERNOTIFYREG   pCur;
    PRTPOWERNOTIFYREG   pNew;

    /*
     * Validation.
     */
    AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
    AssertReturn(g_hRTPowerNotifySpinLock != NIL_RTSPINLOCK, VERR_WRONG_ORDER);
    RT_ASSERT_PREEMPTIBLE();

    RTSpinlockAcquire(g_hRTPowerNotifySpinLock);
    for (pCur = g_pRTPowerCallbackHead; pCur; pCur = pCur->pNext)
        if (    pCur->pvUser == pvUser
            &&  pCur->pfnCallback == pfnCallback)
            break;
    RTSpinlockRelease(g_hRTPowerNotifySpinLock);
    AssertMsgReturn(!pCur, ("pCur=%p pfnCallback=%p pvUser=%p\n", pCur, pfnCallback, pvUser), VERR_ALREADY_EXISTS);

    /*
     * Allocate a new record and attempt to insert it.
     */
    pNew = (PRTPOWERNOTIFYREG)RTMemAlloc(sizeof(*pNew));
    if (!pNew)
        return VERR_NO_MEMORY;

    pNew->pNext = NULL;
    pNew->pfnCallback = pfnCallback;
    pNew->pvUser = pvUser;
    memset(&pNew->bmDone[0], 0xff, sizeof(pNew->bmDone));

    RTSpinlockAcquire(g_hRTPowerNotifySpinLock);

    pCur = g_pRTPowerCallbackHead;
    if (!pCur)
        g_pRTPowerCallbackHead = pNew;
    else
    {
        for (pCur = g_pRTPowerCallbackHead; ; pCur = pCur->pNext)
            if (    pCur->pvUser == pvUser
                &&  pCur->pfnCallback == pfnCallback)
                break;
            else if (!pCur->pNext)
            {
                pCur->pNext = pNew;
                pCur = NULL;
                break;
            }
    }

    ASMAtomicIncU32(&g_iRTPowerGeneration);

    RTSpinlockRelease(g_hRTPowerNotifySpinLock);

    /* duplicate? */
    if (pCur)
    {
        RTMemFree(pCur);
        AssertMsgFailedReturn(("pCur=%p pfnCallback=%p pvUser=%p\n", pCur, pfnCallback, pvUser), VERR_ALREADY_EXISTS);
    }

    return VINF_SUCCESS;
}
Exemple #18
0
RTDECL(int) RTGetOpt(PRTGETOPTSTATE pState, PRTGETOPTUNION pValueUnion)
{
    /*
     * Reset the variables kept in state.
     */
    pState->pDef = NULL;
    pState->uIndex = UINT32_MAX;

    /*
     * Make sure the union is completely cleared out, whatever happens below.
     */
    pValueUnion->u64 = 0;
    pValueUnion->pDef = NULL;

    /*
     * The next option.
     */
    bool            fShort;
    int             iThis;
    const char     *pszArgThis;
    PCRTGETOPTDEF   pOpt;

    if (pState->pszNextShort)
    {
        /*
         * We've got short options left over from the previous call.
         */
        pOpt = rtGetOptSearchShort(*pState->pszNextShort, pState->paOptions, pState->cOptions, pState->fFlags);
        if (!pOpt)
        {
            pValueUnion->psz = pState->pszNextShort;
            return VERR_GETOPT_UNKNOWN_OPTION;
        }
        pState->pszNextShort++;
        pszArgThis = pState->pszNextShort - 2;
        iThis = pState->iNext;
        fShort = true;
    }
    else
    {
        /*
         * Pop off the next argument.  Sorting options and dealing with the
         * dash-dash makes this a little extra complicated.
         */
        for (;;)
        {
            if (pState->iNext >= pState->argc)
                return 0;

            if (pState->cNonOptions)
            {
                if (pState->cNonOptions == INT32_MAX)
                {
                    pValueUnion->psz = pState->argv[pState->iNext++];
                    return VINF_GETOPT_NOT_OPTION;
                }

                if (pState->iNext + pState->cNonOptions >= pState->argc)
                {
                    pState->cNonOptions = INT32_MAX;
                    continue;
                }
            }

            iThis = pState->iNext++;
            pszArgThis = pState->argv[iThis + pState->cNonOptions];

            /*
             * Do a long option search first and then a short option one.
             * This way we can make sure single dash long options doesn't
             * get mixed up with short ones.
             */
            pOpt = rtGetOptSearchLong(pszArgThis, pState->paOptions, pState->cOptions, pState->fFlags);
            if (    !pOpt
                &&  pszArgThis[0] == '-'
                &&  pszArgThis[1] != '-'
                &&  pszArgThis[1] != '\0')
            {
                pOpt = rtGetOptSearchShort(pszArgThis[1], pState->paOptions, pState->cOptions, pState->fFlags);
                fShort = pOpt != NULL;
            }
            else
                fShort = false;

            /* Look for dash-dash. */
            if (!pOpt && !strcmp(pszArgThis, "--"))
            {
                rtGetOptMoveArgvEntries(&pState->argv[iThis], &pState->argv[iThis + pState->cNonOptions]);
                pState->cNonOptions = INT32_MAX;
                continue;
            }

            /* Options first hacks. */
            if (pState->fFlags & RTGETOPTINIT_FLAGS_OPTS_FIRST)
            {
                if (pOpt)
                    rtGetOptMoveArgvEntries(&pState->argv[iThis], &pState->argv[iThis + pState->cNonOptions]);
                else if (*pszArgThis == '-')
                {
                    pValueUnion->psz = pszArgThis;
                    return VERR_GETOPT_UNKNOWN_OPTION;
                }
                else
                {
                    /* not an option, add it to the non-options and try again. */
                    pState->iNext--;
                    pState->cNonOptions++;

                    /* Switch to returning non-options if we've reached the end. */
                    if (pState->iNext + pState->cNonOptions >= pState->argc)
                        pState->cNonOptions = INT32_MAX;
                    continue;
                }
            }

            /* done */
            break;
        }
    }

    if (pOpt)
    {
        pValueUnion->pDef = pOpt; /* in case of no value or error. */

        if ((pOpt->fFlags & RTGETOPT_REQ_MASK) != RTGETOPT_REQ_NOTHING)
        {
            /*
             * Find the argument value.
             *
             * A value is required with the argument. We're trying to be
             * understanding here and will permit any of the following:
             *      -svalue, -s value, -s:value and -s=value
             * (Ditto for long options.)
             */
            const char *pszValue;
            if (fShort)
            {
                if (pszArgThis[2] == '\0')
                {
                    if (iThis + 1 >= pState->argc)
                        return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
                    pszValue = pState->argv[iThis + pState->cNonOptions + 1];
                    rtGetOptMoveArgvEntries(&pState->argv[iThis + 1], &pState->argv[iThis + pState->cNonOptions + 1]);
                    pState->iNext++;
                }
                else /* same argument. */
                    pszValue = &pszArgThis[2  + (pszArgThis[2] == ':' || pszArgThis[2] == '=')];
                if (pState->pszNextShort)
                {
                    pState->pszNextShort = NULL;
                    pState->iNext++;
                }
            }
            else
            {
                size_t cchLong = strlen(pOpt->pszLong);
                if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
                {

                    if (pszArgThis[cchLong] == '\0')
                        return VERR_GETOPT_INDEX_MISSING;

                    uint32_t uIndex;
                    char *pszRet = NULL;
                    int rc = RTStrToUInt32Ex(&pszArgThis[cchLong], &pszRet, 10, &uIndex);
                    if (rc == VWRN_TRAILING_CHARS)
                    {
                        if (   pszRet[0] != ':'
                            && pszRet[0] != '=')
                            return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
                        pState->uIndex = uIndex;
                        pszValue = pszRet + 1;
                    }
                    else if (rc == VINF_SUCCESS)
                    {
                        if (iThis + 1 >= pState->argc)
                            return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
                        pState->uIndex = uIndex;
                        pszValue = pState->argv[iThis + pState->cNonOptions + 1];
                        rtGetOptMoveArgvEntries(&pState->argv[iThis + 1], &pState->argv[iThis + pState->cNonOptions + 1]);
                        pState->iNext++;
                    }
                    else
                        AssertMsgFailedReturn(("%s\n", pszArgThis), VERR_GETOPT_INVALID_ARGUMENT_FORMAT); /* search bug */
                }
                else
                {
                    if (pszArgThis[cchLong] == '\0')
                    {
                        if (iThis + 1 >= pState->argc)
                            return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
                        pszValue = pState->argv[iThis + pState->cNonOptions + 1];
                        rtGetOptMoveArgvEntries(&pState->argv[iThis + 1], &pState->argv[iThis + pState->cNonOptions + 1]);
                        pState->iNext++;
                    }
                    else /* same argument. */
                        pszValue = &pszArgThis[cchLong + 1];
                }
            }

            /*
             * Set up the ValueUnion.
             */
            int rc = rtGetOptProcessValue(pOpt->fFlags, pszValue, pValueUnion);
            if (RT_FAILURE(rc))
                return rc;
        }
        else if (fShort)
        {
            /*
             * Deal with "compressed" short option lists, correcting the next
             * state variables for the start and end cases.
             */
            if (pszArgThis[2])
            {
                if (!pState->pszNextShort)
                {
                    /* start */
                    pState->pszNextShort = &pszArgThis[2];
                    pState->iNext--;
                }
            }
            else if (pState->pszNextShort)
            {
                /* end */
                pState->pszNextShort = NULL;
                pState->iNext++;
            }
        }
        else if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
        {
            size_t cchLong = strlen(pOpt->pszLong);
            if (pszArgThis[cchLong] == '\0')
                return VERR_GETOPT_INDEX_MISSING;

            uint32_t uIndex;
            if (RTStrToUInt32Full(&pszArgThis[cchLong], 10, &uIndex) == VINF_SUCCESS)
                pState->uIndex = uIndex;
            else
                AssertMsgFailedReturn(("%s\n", pszArgThis), VERR_GETOPT_INVALID_ARGUMENT_FORMAT); /* search bug */
        }

        pState->pDef = pOpt;
        return pOpt->iShort;
    }

    /*
     * Not a known option argument. If it starts with a switch char (-) we'll
     * fail with unknown option, and if it doesn't we'll return it as a non-option.
     */
    if (*pszArgThis == '-')
    {
        pValueUnion->psz = pszArgThis;
        return VERR_GETOPT_UNKNOWN_OPTION;
    }

    pValueUnion->psz = pszArgThis;
    return VINF_GETOPT_NOT_OPTION;
}
Exemple #19
0
/**
 * Internal worker routine.
 *
 * On x86 the typical stack frame layout is like this:
 *     ..  ..
 *     16  parameter 2
 *     12  parameter 1
 *      8  parameter 0
 *      4  return address
 *      0  old ebp; current ebp points here
 *
 * @todo Add AMD64 support (needs teaming up with the module management for
 *       unwind tables).
 */
static int dbgfR3StackWalk(PUVM pUVM, VMCPUID idCpu, RTDBGAS hAs, PDBGFSTACKFRAME pFrame)
{
    /*
     * Stop if we got a read error in the previous run.
     */
    if (pFrame->fFlags & DBGFSTACKFRAME_FLAGS_LAST)
        return VERR_NO_MORE_FILES;

    /*
     * Read the raw frame data.
     */
    const DBGFADDRESS AddrOldPC = pFrame->AddrPC;
    const unsigned cbRetAddr = DBGFReturnTypeSize(pFrame->enmReturnType);
    unsigned cbStackItem;
    switch (AddrOldPC.fFlags & DBGFADDRESS_FLAGS_TYPE_MASK)
    {
        case DBGFADDRESS_FLAGS_FAR16: cbStackItem = 2; break;
        case DBGFADDRESS_FLAGS_FAR32: cbStackItem = 4; break;
        case DBGFADDRESS_FLAGS_FAR64: cbStackItem = 8; break;
        case DBGFADDRESS_FLAGS_RING0: cbStackItem = sizeof(RTHCUINTPTR); break;
        default:
            switch (pFrame->enmReturnType)
            {
                case DBGFRETURNTYPE_FAR16:
                case DBGFRETURNTYPE_IRET16:
                case DBGFRETURNTYPE_IRET32_V86:
                case DBGFRETURNTYPE_NEAR16: cbStackItem = 2; break;

                case DBGFRETURNTYPE_FAR32:
                case DBGFRETURNTYPE_IRET32:
                case DBGFRETURNTYPE_IRET32_PRIV:
                case DBGFRETURNTYPE_NEAR32: cbStackItem = 4; break;

                case DBGFRETURNTYPE_FAR64:
                case DBGFRETURNTYPE_IRET64:
                case DBGFRETURNTYPE_NEAR64: cbStackItem = 8; break;

                default:
                    AssertMsgFailed(("%d\n", pFrame->enmReturnType));
                    cbStackItem = 4;
                    break;
            }
    }

    union
    {
        uint64_t *pu64;
        uint32_t *pu32;
        uint16_t *pu16;
        uint8_t  *pb;
        void     *pv;
    } u, uRet, uArgs, uBp;
    size_t cbRead = cbRetAddr + cbStackItem + sizeof(pFrame->Args);
    u.pv = alloca(cbRead);
    uBp = u;
    uRet.pb = u.pb + cbStackItem;
    uArgs.pb = u.pb + cbStackItem + cbRetAddr;

    Assert(DBGFADDRESS_IS_VALID(&pFrame->AddrFrame));
    int rc = dbgfR3Read(pUVM, idCpu, u.pv,
                        pFrame->fFlags & DBGFSTACKFRAME_FLAGS_ALL_VALID
                        ? &pFrame->AddrReturnFrame
                        : &pFrame->AddrFrame,
                        cbRead, &cbRead);
    if (    RT_FAILURE(rc)
        ||  cbRead < cbRetAddr + cbStackItem)
        pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_LAST;

    /*
     * The first step is taken in a different way than the others.
     */
    if (!(pFrame->fFlags & DBGFSTACKFRAME_FLAGS_ALL_VALID))
    {
        pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_ALL_VALID;
        pFrame->iFrame = 0;

        /* Current PC - set by caller, just find symbol & line. */
        if (DBGFADDRESS_IS_VALID(&pFrame->AddrPC))
        {
            pFrame->pSymPC  = DBGFR3AsSymbolByAddrA(pUVM, hAs, &pFrame->AddrPC, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL,
                                                    NULL /*poffDisp*/, NULL /*phMod*/);
            pFrame->pLinePC = DBGFR3AsLineByAddrA(pUVM, hAs, &pFrame->AddrPC, NULL /*poffDisp*/, NULL /*phMod*/);
        }
    }
    else /* 2nd and subsequent steps */
    {
        /* frame, pc and stack is taken from the existing frames return members. */
        pFrame->AddrFrame = pFrame->AddrReturnFrame;
        pFrame->AddrPC    = pFrame->AddrReturnPC;
        pFrame->pSymPC    = pFrame->pSymReturnPC;
        pFrame->pLinePC   = pFrame->pLineReturnPC;

        /* increment the frame number. */
        pFrame->iFrame++;
    }

    /*
     * Return Frame address.
     */
    pFrame->AddrReturnFrame = pFrame->AddrFrame;
    switch (cbStackItem)
    {
        case 2:    pFrame->AddrReturnFrame.off = *uBp.pu16; break;
        case 4:    pFrame->AddrReturnFrame.off = *uBp.pu32; break;
        case 8:    pFrame->AddrReturnFrame.off = *uBp.pu64; break;
        default:    AssertMsgFailedReturn(("cbStackItem=%d\n", cbStackItem), VERR_DBGF_STACK_IPE_1);
    }
    pFrame->AddrReturnFrame.FlatPtr += pFrame->AddrReturnFrame.off - pFrame->AddrFrame.off;

    /*
     * Return PC and Stack Addresses.
     */
    /** @todo AddrReturnStack is not correct for stdcall and pascal. (requires scope info) */
    pFrame->AddrReturnStack          = pFrame->AddrFrame;
    pFrame->AddrReturnStack.off     += cbStackItem + cbRetAddr;
    pFrame->AddrReturnStack.FlatPtr += cbStackItem + cbRetAddr;

    pFrame->AddrReturnPC             = pFrame->AddrPC;
    switch (pFrame->enmReturnType)
    {
        case DBGFRETURNTYPE_NEAR16:
            if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC))
            {
                pFrame->AddrReturnPC.FlatPtr += *uRet.pu16 - pFrame->AddrReturnPC.off;
                pFrame->AddrReturnPC.off      = *uRet.pu16;
            }
            else
                DBGFR3AddrFromFlat(pUVM, &pFrame->AddrReturnPC, *uRet.pu16);
            break;
        case DBGFRETURNTYPE_NEAR32:
            if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC))
            {
                pFrame->AddrReturnPC.FlatPtr += *uRet.pu32 - pFrame->AddrReturnPC.off;
                pFrame->AddrReturnPC.off      = *uRet.pu32;
            }
            else
                DBGFR3AddrFromFlat(pUVM, &pFrame->AddrReturnPC, *uRet.pu32);
            break;
        case DBGFRETURNTYPE_NEAR64:
            if (DBGFADDRESS_IS_VALID(&pFrame->AddrReturnPC))
            {
                pFrame->AddrReturnPC.FlatPtr += *uRet.pu64 - pFrame->AddrReturnPC.off;
                pFrame->AddrReturnPC.off      = *uRet.pu64;
            }
            else
                DBGFR3AddrFromFlat(pUVM, &pFrame->AddrReturnPC, *uRet.pu64);
            break;
        case DBGFRETURNTYPE_FAR16:
            DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]);
            break;
        case DBGFRETURNTYPE_FAR32:
            DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]);
            break;
        case DBGFRETURNTYPE_FAR64:
            DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]);
            break;
        case DBGFRETURNTYPE_IRET16:
            DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[1], uRet.pu16[0]);
            break;
        case DBGFRETURNTYPE_IRET32:
            DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]);
            break;
        case DBGFRETURNTYPE_IRET32_PRIV:
            DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]);
            break;
        case DBGFRETURNTYPE_IRET32_V86:
            DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[2], uRet.pu32[0]);
            break;
        case DBGFRETURNTYPE_IRET64:
            DBGFR3AddrFromSelOff(pUVM, idCpu, &pFrame->AddrReturnPC, uRet.pu16[4], uRet.pu64[0]);
            break;
        default:
            AssertMsgFailed(("enmReturnType=%d\n", pFrame->enmReturnType));
            return VERR_INVALID_PARAMETER;
    }

    pFrame->pSymReturnPC  = DBGFR3AsSymbolByAddrA(pUVM, hAs, &pFrame->AddrReturnPC, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL,
                                                  NULL /*poffDisp*/, NULL /*phMod*/);
    pFrame->pLineReturnPC = DBGFR3AsLineByAddrA(pUVM, hAs, &pFrame->AddrReturnPC, NULL /*poffDisp*/, NULL /*phMod*/);

    /*
     * Frame bitness flag.
     */
    switch (cbStackItem)
    {
        case 2: pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_16BIT; break;
        case 4: pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_32BIT; break;
        case 8: pFrame->fFlags |= DBGFSTACKFRAME_FLAGS_64BIT; break;
        default:    AssertMsgFailedReturn(("cbStackItem=%d\n", cbStackItem), VERR_DBGF_STACK_IPE_2);
    }

    /*
     * The arguments.
     */
    memcpy(&pFrame->Args, uArgs.pv, sizeof(pFrame->Args));

    return VINF_SUCCESS;
}
int vboxClipboardUtf16WinToLin(PRTUTF16 pwszSrc, size_t cwSrc, PRTUTF16 pu16Dest,
                               size_t cwDest)
{
    size_t cwDestPos;

    LogFlowFunc(("pwszSrc=%.*ls, cwSrc=%u, pu16Dest=%p, cwDest=%u\n",
                 cwSrc, pwszSrc, cwSrc, pu16Dest, cwDest));
    /* A buffer of size 0 may not be an error, but it is not a good idea either. */
    Assert(cwDest > 0);
    if (!VALID_PTR(pwszSrc) || !VALID_PTR(pu16Dest))
    {
        LogRel(("vboxClipboardUtf16WinToLin: received an invalid ptr, pwszSrc=%p, pu16Dest=%p, returning VERR_INVALID_PARAMETER\n", pwszSrc, pu16Dest));
        AssertReturn(VALID_PTR(pwszSrc) && VALID_PTR(pu16Dest), VERR_INVALID_PARAMETER);
    }
    /* We only take little endian Utf16 */
    if (pwszSrc[0] == UTF16BEMARKER)
    {
        LogRel(("vboxClipboardUtf16WinToLin: received a big endian Utf16 string, returning VERR_INVALID_PARAMETER\n"));
        AssertMsgFailedReturn(("received a big endian string\n"), VERR_INVALID_PARAMETER);
    }
    if (cwDest == 0)
    {
        LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
        return VERR_BUFFER_OVERFLOW;
    }
    if (cwSrc == 0)
    {
        pu16Dest[0] = 0;
        LogFlowFunc(("received empty string.  Returning VINF_SUCCESS\n"));
        return VINF_SUCCESS;
    }
    /* Prepend the Utf16 byte order marker if it is missing. */
    if (pwszSrc[0] == UTF16LEMARKER)
    {
        cwDestPos = 0;
    }
    else
    {
        pu16Dest[0] = UTF16LEMARKER;
        cwDestPos = 1;
    }
    for (size_t i = 0; i < cwSrc; ++i, ++cwDestPos)
    {
        if (pwszSrc[i] == 0)
        {
            break;
        }
        if (cwDestPos == cwDest)
        {
            LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
            return VERR_BUFFER_OVERFLOW;
        }
        if (   (i + 1 < cwSrc)
            && (pwszSrc[i] == CARRIAGERETURN)
            && (pwszSrc[i + 1] == LINEFEED))
        {
            ++i;
        }
        pu16Dest[cwDestPos] = pwszSrc[i];
    }
    /* Terminating zero */
    if (cwDestPos == cwDest)
    {
        LogFlowFunc(("returning VERR_BUFFER_OVERFLOW\n"));
        return VERR_BUFFER_OVERFLOW;
    }
    pu16Dest[cwDestPos] = 0;
    LogFlowFunc(("set string %ls.  Returning\n", pu16Dest + 1));
    return VINF_SUCCESS;
}
QString UINativeHotKey::toString(int iKeyCode)
{
    QString strKeyName;

#ifdef Q_WS_WIN
    /* MapVirtualKey doesn't distinguish between right and left vkeys,
     * even under XP, despite that it stated in MSDN. Do it by hands.
     * Besides that it can't recognize such virtual keys as
     * VK_DIVIDE & VK_PAUSE, this is also known bug. */
    int iScan;
    switch (iKeyCode)
    {
        /* Processing special keys... */
        case VK_PAUSE: iScan = 0x45 << 16; break;
        case VK_RSHIFT: iScan = 0x36 << 16; break;
        case VK_RCONTROL: iScan = (0x1D << 16) | (1 << 24); break;
        case VK_RMENU: iScan = (0x38 << 16) | (1 << 24); break;
        /* Processing extended keys... */
        case VK_APPS:
        case VK_LWIN:
        case VK_RWIN:
        case VK_NUMLOCK: iScan = (::MapVirtualKey(iKeyCode, 0) | 256) << 16; break;
        default: iScan = ::MapVirtualKey(iKeyCode, 0) << 16;
    }
    TCHAR *pKeyName = new TCHAR[256];
    if (::GetKeyNameText(iScan, pKeyName, 256))
    {
        strKeyName = QString::fromUtf16(pKeyName);
    }
    else
    {
        AssertMsgFailed(("That key have no name!\n"));
        strKeyName = UIHostComboEditor::tr("<key_%1>").arg(iKeyCode);
    }
    delete[] pKeyName;
#endif /* Q_WS_WIN */

#ifdef Q_WS_X11
    if (char *pNativeKeyName = ::XKeysymToString((KeySym)iKeyCode))
    {
        strKeyName = m_keyNames[pNativeKeyName].isEmpty() ?
                     QString(pNativeKeyName) : m_keyNames[pNativeKeyName];
    }
    else
    {
        AssertMsgFailed(("That key have no name!\n"));
        strKeyName = UIHostComboEditor::tr("<key_%1>").arg(iKeyCode);
    }
#endif /* Q_WS_X11 */

#ifdef Q_WS_MAC
    UInt32 modMask = DarwinKeyCodeToDarwinModifierMask(iKeyCode);
    switch (modMask)
    {
        case shiftKey:
        case optionKey:
        case controlKey:
        case cmdKey:
            strKeyName = UIHostComboEditor::tr("Left ");
            break;
        case rightShiftKey:
        case rightOptionKey:
        case rightControlKey:
        case kEventKeyModifierRightCmdKeyMask:
            strKeyName = UIHostComboEditor::tr("Right ");
            break;
        default:
            AssertMsgFailedReturn(("modMask=%#x\n", modMask), QString());
    }
    switch (modMask)
    {
        case shiftKey:
        case rightShiftKey:
            strKeyName += QChar(kShiftUnicode);
            break;
        case optionKey:
        case rightOptionKey:
            strKeyName += QChar(kOptionUnicode);
            break;
        case controlKey:
        case rightControlKey:
            strKeyName += QChar(kControlUnicode);
            break;
        case cmdKey:
        case kEventKeyModifierRightCmdKeyMask:
            strKeyName += QChar(kCommandUnicode);
            break;
    }
#endif /* Q_WS_MAC */

    return strKeyName;
}
VBGLR3DECL(int) VbglR3DnDProcessNextMessage(CPVBGLR3DNDHGCMEVENT pEvent)
{
    /* Validate input */
    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);

    uint32_t       uMsg       = 0;
    uint32_t       uNumParms  = 0;
    const uint32_t ccbFormats = _64K;
    const uint32_t ccbData    = _1M;
    int rc = vbglR3DnDQueryNextHostMessageType(g_clientId, &uMsg, &uNumParms, true);
    if (RT_SUCCESS(rc))
    {
        DO(("Got message %d\n", uMsg));
        switch(uMsg)
        {
            case DragAndDropSvc::HOST_DND_HG_EVT_ENTER:
            case DragAndDropSvc::HOST_DND_HG_EVT_MOVE:
            case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED:
            {
                pEvent->uType = uMsg;
                pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
                if (!pEvent->pszFormats)
                    return VERR_NO_MEMORY;
                rc = vbglR3DnDHGProcessActionMessage(g_clientId,
                                                     uMsg,
                                                     &pEvent->uScreenId,
                                                     &pEvent->u.a.uXpos,
                                                     &pEvent->u.a.uYpos,
                                                     &pEvent->u.a.uDefAction,
                                                     &pEvent->u.a.uAllActions,
                                                     pEvent->pszFormats,
                                                     ccbFormats,
                                                     &pEvent->cbFormats);
                break;
            }
            case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE:
            {
                pEvent->uType = uMsg;
                rc = vbglR3DnDHGProcessLeaveMessage(g_clientId);
                break;
            }
            case DragAndDropSvc::HOST_DND_HG_SND_DATA:
            {
                pEvent->uType = uMsg;
                pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
                if (!pEvent->pszFormats)
                    return VERR_NO_MEMORY;
                pEvent->u.b.pvData = RTMemAlloc(ccbData);
                if (!pEvent->u.b.pvData)
                {
                    RTMemFree(pEvent->pszFormats);
                    pEvent->pszFormats = NULL;
                    return VERR_NO_MEMORY;
                }
                rc = vbglR3DnDHGProcessSendDataMessage(g_clientId,
                                                       &pEvent->uScreenId,
                                                       pEvent->pszFormats,
                                                       ccbFormats,
                                                       &pEvent->cbFormats,
                                                       &pEvent->u.b.pvData,
                                                       ccbData,
                                                       &pEvent->u.b.cbData);
                break;
            }
#ifdef VBOX_WITH_DRAG_AND_DROP_GH
            case DragAndDropSvc::HOST_DND_GH_REQ_PENDING:
            {
                pEvent->uType = uMsg;
                rc = vbglR3DnDGHProcessRequestPendingMessage(g_clientId,
                                                             &pEvent->uScreenId);
                break;
            }
            case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED:
            {
                pEvent->uType = uMsg;
                pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
                if (!pEvent->pszFormats)
                    return VERR_NO_MEMORY;
                rc = vbglR3DnDGHProcessDroppedMessage(g_clientId,
                                                      pEvent->pszFormats,
                                                      ccbFormats,
                                                      &pEvent->cbFormats,
                                                      &pEvent->u.a.uDefAction);
                break;
            }
#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
            case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
            {
                pEvent->uType = uMsg;
                rc = vbglR3DnDHGProcessCancelMessage(g_clientId);
                if (RT_SUCCESS(rc))
                    rc = VERR_CANCELLED;
                break;
            }
            default: AssertMsgFailedReturn(("Message %u isn't expected in this context", uMsg), VERR_INVALID_PARAMETER); break;
        }
    }
    return rc;
}
Exemple #23
0
/**
 * Converts a kLdr error code to an IPRT one.
 */
static int rtkldrConvertError(int krc)
{
    if (!krc)
        return VINF_SUCCESS;
    switch (krc)
    {
        case KERR_INVALID_PARAMETER:                        return VERR_INVALID_PARAMETER;
        case KERR_INVALID_HANDLE:                           return VERR_INVALID_HANDLE;
        case KERR_NO_MEMORY:                                return VERR_NO_MEMORY;


        case KLDR_ERR_UNKNOWN_FORMAT:
        case KLDR_ERR_MZ_NOT_SUPPORTED:                     return VERR_MZ_EXE_NOT_SUPPORTED;
        case KLDR_ERR_NE_NOT_SUPPORTED:                     return VERR_NE_EXE_NOT_SUPPORTED;
        case KLDR_ERR_LX_NOT_SUPPORTED:                     return VERR_LX_EXE_NOT_SUPPORTED;
        case KLDR_ERR_LE_NOT_SUPPORTED:                     return VERR_LE_EXE_NOT_SUPPORTED;
        case KLDR_ERR_PE_NOT_SUPPORTED:                     return VERR_PE_EXE_NOT_SUPPORTED;
        case KLDR_ERR_ELF_NOT_SUPPORTED:                    return VERR_ELF_EXE_NOT_SUPPORTED;
        case KLDR_ERR_MACHO_NOT_SUPPORTED:                  return VERR_INVALID_EXE_SIGNATURE;
        case KLDR_ERR_AOUT_NOT_SUPPORTED:                   return VERR_AOUT_EXE_NOT_SUPPORTED;

        case KLDR_ERR_MODULE_NOT_FOUND:                     return VERR_MODULE_NOT_FOUND;
        case KLDR_ERR_PREREQUISITE_MODULE_NOT_FOUND:        return VERR_MODULE_NOT_FOUND;
        case KLDR_ERR_MAIN_STACK_ALLOC_FAILED:              return VERR_NO_MEMORY;
        case KERR_BUFFER_OVERFLOW:                          return VERR_BUFFER_OVERFLOW;
        case KLDR_ERR_SYMBOL_NOT_FOUND:                     return VERR_SYMBOL_NOT_FOUND;
        case KLDR_ERR_FORWARDER_SYMBOL:                     return VERR_BAD_EXE_FORMAT;
        case KLDR_ERR_BAD_FIXUP:                            AssertMsgFailedReturn(("KLDR_ERR_BAD_FIXUP\n"), VERR_BAD_EXE_FORMAT);
        case KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS:         return VERR_BAD_EXE_FORMAT;
        case KLDR_ERR_NO_DEBUG_INFO:                        return VERR_FILE_NOT_FOUND;
        case KLDR_ERR_ALREADY_MAPPED:                       return VERR_WRONG_ORDER;
        case KLDR_ERR_NOT_MAPPED:                           return VERR_WRONG_ORDER;
        case KLDR_ERR_ADDRESS_OVERFLOW:                     return VERR_NUMBER_TOO_BIG;
        case KLDR_ERR_TODO:                                 return VERR_NOT_IMPLEMENTED;

        case KLDR_ERR_NOT_LOADED_DYNAMICALLY:
        case KCPU_ERR_ARCH_CPU_NOT_COMPATIBLE:
        case KLDR_ERR_TOO_LONG_FORWARDER_CHAIN:
        case KLDR_ERR_MODULE_TERMINATING:
        case KLDR_ERR_PREREQUISITE_MODULE_TERMINATING:
        case KLDR_ERR_MODULE_INIT_FAILED:
        case KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED:
        case KLDR_ERR_MODULE_INIT_FAILED_ALREADY:
        case KLDR_ERR_PREREQUISITE_MODULE_INIT_FAILED_ALREADY:
        case KLDR_ERR_PREREQUISITE_RECURSED_TOO_DEEPLY:
        case KLDR_ERR_THREAD_ATTACH_FAILED:
        case KRDR_ERR_TOO_MANY_MAPPINGS:
        case KLDR_ERR_NOT_DLL:
        case KLDR_ERR_NOT_EXE:
            AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_GENERAL_FAILURE);


        case KLDR_ERR_PE_UNSUPPORTED_MACHINE:
        case KLDR_ERR_PE_BAD_FILE_HEADER:
        case KLDR_ERR_PE_BAD_OPTIONAL_HEADER:
        case KLDR_ERR_PE_BAD_SECTION_HEADER:
        case KLDR_ERR_PE_BAD_FORWARDER:
        case KLDR_ERR_PE_FORWARDER_IMPORT_NOT_FOUND:
        case KLDR_ERR_PE_BAD_FIXUP:
        case KLDR_ERR_PE_BAD_IMPORT:
            AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_GENERAL_FAILURE);

        case KLDR_ERR_LX_BAD_HEADER:
        case KLDR_ERR_LX_BAD_LOADER_SECTION:
        case KLDR_ERR_LX_BAD_FIXUP_SECTION:
        case KLDR_ERR_LX_BAD_OBJECT_TABLE:
        case KLDR_ERR_LX_BAD_PAGE_MAP:
        case KLDR_ERR_LX_BAD_ITERDATA:
        case KLDR_ERR_LX_BAD_ITERDATA2:
        case KLDR_ERR_LX_BAD_BUNDLE:
        case KLDR_ERR_LX_NO_SONAME:
        case KLDR_ERR_LX_BAD_SONAME:
        case KLDR_ERR_LX_BAD_FORWARDER:
        case KLDR_ERR_LX_NRICHAIN_NOT_SUPPORTED:
            AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_GENERAL_FAILURE);

        case KLDR_ERR_MACHO_OTHER_ENDIAN_NOT_SUPPORTED:
        case KLDR_ERR_MACHO_BAD_HEADER:
        case KLDR_ERR_MACHO_UNSUPPORTED_FILE_TYPE:
        case KLDR_ERR_MACHO_UNSUPPORTED_MACHINE:
        case KLDR_ERR_MACHO_BAD_LOAD_COMMAND:
        case KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND:
        case KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND:
        case KLDR_ERR_MACHO_BAD_SECTION:
        case KLDR_ERR_MACHO_UNSUPPORTED_SECTION:
#ifdef KLDR_ERR_MACHO_UNSUPPORTED_INIT_SECTION
        case KLDR_ERR_MACHO_UNSUPPORTED_INIT_SECTION:
        case KLDR_ERR_MACHO_UNSUPPORTED_TERM_SECTION:
#endif
        case KLDR_ERR_MACHO_UNKNOWN_SECTION:
        case KLDR_ERR_MACHO_BAD_SECTION_ORDER:
        case KLDR_ERR_MACHO_BIT_MIX:
        case KLDR_ERR_MACHO_BAD_OBJECT_FILE:
        case KLDR_ERR_MACHO_BAD_SYMBOL:
        case KLDR_ERR_MACHO_UNSUPPORTED_FIXUP_TYPE:
            AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_GENERAL_FAILURE);

        default:
            if (RT_FAILURE(krc))
                return krc;
            AssertMsgFailedReturn(("krc=%d (%#x): %s\n", krc, krc, kErrName(krc)), VERR_NO_TRANSLATION);
    }
}
extern "C" int RTWinSocketPair(int domain, int type, int protocol, SOCKET socket_vector[2])
{
    LogFlowFunc(("ENTER: domain:%d, type:%d, protocol:%d, socket_vector:%p\n",
		 domain, type, protocol, socket_vector));
    switch (domain)
    {
    case AF_INET:
	break;
    case AF_INET6: /* I dobt we really need it. */
    default:
	AssertMsgFailedReturn(("Unsuported domain:%d\n", domain), 
	  		      VERR_INVALID_PARAMETER);
    }
    
    switch(type)
    {
    case SOCK_STREAM:
    case SOCK_DGRAM:
	break;
    default:
	AssertMsgFailedReturn(("Unsuported type:%d\n", type), 
	 		      VERR_INVALID_PARAMETER);
    }
    
    AssertPtrReturn(socket_vector, VERR_INVALID_PARAMETER);
    if (!socket_vector)
      return VERR_INVALID_PARAMETER;

    socket_vector[0] = socket_vector[1] = INVALID_SOCKET;

    SOCKET listener = INVALID_SOCKET;
    
    union {
	struct sockaddr_in in_addr;
	struct sockaddr addr;
    } sa[2];

    int cb = sizeof(sa);
    memset(&sa, 0, cb);

    sa[0].in_addr.sin_family = domain;
    sa[0].in_addr.sin_addr.s_addr = RT_H2N_U32(INADDR_LOOPBACK);
    sa[0].in_addr.sin_port = 0;
    cb = sizeof(sa[0]);

    if (type == SOCK_STREAM)
    {
	listener = WSASocket(domain, type, protocol, 0, NULL, 0);
    
	if (listener == INVALID_SOCKET)
	{
	    return VERR_INTERNAL_ERROR;
	}
    
	int reuse = 1;
	cb = sizeof(int);
	int rc = setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, cb);

	if (rc)
	{
	    goto close_socket;
	}
    
	cb = sizeof(sa[0]);
	rc = bind(listener, &sa[0].addr, cb);
	if(rc)
	{
	    goto close_socket;
	}

	memset(&sa[0], 0, cb);
	rc = getsockname(listener, &sa[0].addr, &cb);
	if (rc)
	{
	    goto close_socket;
	}

	rc = listen(listener, 1);
	if (rc)
	{
	    goto close_socket;
	}
    
	socket_vector[0] = WSASocket(domain, type, protocol, 0, NULL, 0);
	if (socket_vector[0] == INVALID_SOCKET)
	{
	    goto close_socket;
	}

	rc = connect(socket_vector[0], &sa[0].addr, cb);
	if (rc)
	  goto close_socket;

    
	socket_vector[1] = accept(listener, NULL, NULL);
	if (socket_vector[1] == INVALID_SOCKET)
	{
	    goto close_socket;
	}

	closesocket(listener);
    }
    else
    {
	socket_vector[0] = WSASocket(domain, type, protocol, 0, NULL, 0);
	
	cb = sizeof(sa[0]);
	int rc = bind(socket_vector[0], &sa[0].addr, cb);
	Assert(rc != SOCKET_ERROR);
	if (rc == SOCKET_ERROR)
	{
	    goto close_socket;
	}

	sa[1].in_addr.sin_family = domain;
	sa[1].in_addr.sin_addr.s_addr = RT_H2N_U32(INADDR_LOOPBACK);
	sa[1].in_addr.sin_port = 0;

	socket_vector[1] = WSASocket(domain, type, protocol, 0, NULL, 0);
	rc = bind(socket_vector[1], &sa[1].addr, cb);
	Assert(rc != SOCKET_ERROR);
	if (rc == SOCKET_ERROR)
	{
	    goto close_socket;
	}

	{
	    u_long mode = 0;
	    rc = ioctlsocket(socket_vector[0], FIONBIO, &mode);
	    AssertMsgReturn(rc != SOCKET_ERROR, 
			    ("ioctl error: %d\n", WSAGetLastError()),
			    VERR_INTERNAL_ERROR);

	    rc = ioctlsocket(socket_vector[1], FIONBIO, &mode);
	    AssertMsgReturn(rc != SOCKET_ERROR, 
			    ("ioctl error: %d\n", WSAGetLastError()),
			    VERR_INTERNAL_ERROR);
	}

	memset(&sa, 0, 2 * cb);
	rc = getsockname(socket_vector[0], &sa[0].addr, &cb);
	Assert(rc != SOCKET_ERROR);
	if (rc == SOCKET_ERROR)
	{
	    goto close_socket;
	}

	rc = getsockname(socket_vector[1], &sa[1].addr, &cb);
	Assert(rc != SOCKET_ERROR);
	if (rc == SOCKET_ERROR)
	{
	    goto close_socket;
	}

	rc = connect(socket_vector[0], &sa[1].addr, cb);
	Assert(rc != SOCKET_ERROR);
	if (rc == SOCKET_ERROR)
	{
	    goto close_socket;
	}

	rc = connect(socket_vector[1], &sa[0].addr, cb);
	Assert(rc != SOCKET_ERROR);
	if (rc == SOCKET_ERROR)
	{
	    goto close_socket;
	}
    }
    LogFlowFuncLeaveRC(VINF_SUCCESS);
    return VINF_SUCCESS;

close_socket:
    if (listener != INVALID_SOCKET)
      closesocket(listener);

    if (socket_vector[0] != INVALID_SOCKET)
      closesocket(socket_vector[0]);

    if (socket_vector[1] != INVALID_SOCKET)
      closesocket(socket_vector[1]);

    LogFlowFuncLeaveRC(VERR_INTERNAL_ERROR);
    return VERR_INTERNAL_ERROR;
}
Exemple #25
0
/** @copydoc RTDBGMODVTDBG::pfnSegmentAdd */
static DECLCALLBACK(int) rtDbgModContainer_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, size_t cchName,
                                                      uint32_t fFlags, PRTDBGSEGIDX piSeg)
{
    PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv;

    /*
     * Input validation (the bits the caller cannot do).
     */
    /* Overlapping segments are not yet supported. Will use flags to deal with it if it becomes necessary. */
    RTUINTPTR   uRvaLast    = uRva + RT_MAX(cb, 1) - 1;
    RTUINTPTR   uRvaLastMax = uRvaLast;
    RTDBGSEGIDX iSeg        = pThis->cSegs;
    while (iSeg-- > 0)
    {
        RTUINTPTR uCurRva     = pThis->paSegs[iSeg].off;
        RTUINTPTR uCurRvaLast = uCurRva + RT_MAX(pThis->paSegs[iSeg].cb, 1) - 1;
        if (   uRva      <= uCurRvaLast
            && uRvaLast  >= uCurRva
            && (   /* HACK ALERT! Allow empty segments to share space (bios/watcom, elf). */
                   (cb != 0 && pThis->paSegs[iSeg].cb != 0)
                || (   cb == 0
                    && uRva != uCurRva
                    && uRva != uCurRvaLast)
                || (    pThis->paSegs[iSeg].cb == 0
                    && uCurRva != uRva
                    && uCurRva != uRvaLast)
               )
           )
            AssertMsgFailedReturn(("uRva=%RTptr uRvaLast=%RTptr (cb=%RTptr) \"%s\";\n"
                                   "uRva=%RTptr uRvaLast=%RTptr (cb=%RTptr) \"%s\" iSeg=%#x\n",
                                   uRva, uRvaLast, cb, pszName,
                                   uCurRva, uCurRvaLast, pThis->paSegs[iSeg].cb, pThis->paSegs[iSeg].pszName, iSeg),
                                  VERR_DBG_SEGMENT_INDEX_CONFLICT);
        if (uRvaLastMax < uCurRvaLast)
            uRvaLastMax = uCurRvaLast;
    }
    /* Strict ordered segment addition at the moment. */
    iSeg = pThis->cSegs;
    AssertMsgReturn(!piSeg || *piSeg == NIL_RTDBGSEGIDX || *piSeg == iSeg,
                    ("iSeg=%#x *piSeg=%#x\n", iSeg, *piSeg),
                    VERR_DBG_INVALID_SEGMENT_INDEX);

    /*
     * Add an entry to the segment table, extending it if necessary.
     */
    if (!(iSeg % 8))
    {
        void *pvSegs = RTMemRealloc(pThis->paSegs, sizeof(RTDBGMODCTNSEGMENT) * (iSeg + 8));
        if (!pvSegs)
            return VERR_NO_MEMORY;
        pThis->paSegs = (PRTDBGMODCTNSEGMENT)pvSegs;
    }

    pThis->paSegs[iSeg].SymAddrTree     = NULL;
    pThis->paSegs[iSeg].LineAddrTree    = NULL;
    pThis->paSegs[iSeg].off             = uRva;
    pThis->paSegs[iSeg].cb              = cb;
    pThis->paSegs[iSeg].fFlags          = fFlags;
    pThis->paSegs[iSeg].pszName         = RTStrCacheEnterN(g_hDbgModStrCache, pszName, cchName);
    if (pThis->paSegs[iSeg].pszName)
    {
        if (piSeg)
            *piSeg = iSeg;
        pThis->cSegs++;
        pThis->cb = uRvaLastMax + 1;
        if (!pThis->cb)
            pThis->cb = RTUINTPTR_MAX;
        return VINF_SUCCESS;
    }
    return VERR_NO_MEMORY;
}