Exemple #1
0
DECLCALLBACK(void) Keyboard::keyboardLedStatusChange(PPDMIKEYBOARDCONNECTOR pInterface, PDMKEYBLEDS enmLeds)
{
    PDRVMAINKEYBOARD pDrv = PPDMIKEYBOARDCONNECTOR_2_MAINKEYBOARD(pInterface);
    pDrv->pKeyboard->getParent()->onKeyboardLedsChange(RT_BOOL(enmLeds & PDMKEYBLEDS_NUMLOCK),
            RT_BOOL(enmLeds & PDMKEYBLEDS_CAPSLOCK),
            RT_BOOL(enmLeds & PDMKEYBLEDS_SCROLLLOCK));
}
Exemple #2
0
HRESULT ParallelPort::setEnabled(BOOL aEnabled)
{
    LogFlowThisFunc(("aEnabled=%RTbool\n", aEnabled));
    /* the machine needs to be mutable */
    AutoMutableStateDependency adep(m->pMachine);
    if (FAILED(adep.rc())) return adep.rc();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (m->bd->fEnabled != RT_BOOL(aEnabled))
    {
        m->bd.backup();
        m->bd->fEnabled = RT_BOOL(aEnabled);

        m->fModified = true;
        // leave the lock before informing callbacks
        alock.release();

        AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
        m->pMachine->i_setModified(Machine::IsModified_ParallelPorts);
        mlock.release();

        m->pMachine->i_onParallelPortChange(this);
    }

    return S_OK;
}
HRESULT SerialPort::setServer(BOOL aServer)
{
    /* the machine needs to be mutable */
    AutoMutableOrSavedStateDependency adep(m->pMachine);
    if (FAILED(adep.rc())) return adep.rc();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (m->bd->fServer != RT_BOOL(aServer))
    {
        m->bd.backup();
        m->bd->fServer = RT_BOOL(aServer);

        m->fModified = true;
        // leave the lock before informing callbacks
        alock.release();

        AutoWriteLock mlock(m->pMachine COMMA_LOCKVAL_SRC_POS);
        m->pMachine->i_setModified(Machine::IsModified_SerialPorts);
        mlock.release();

        m->pMachine->i_onSerialPortChange(this);
    }

    return S_OK;
}
HRESULT USBDeviceFilter::setActive(const BOOL aActive)
{
    /* the machine needs to be mutable */
    AutoMutableOrSavedOrRunningStateDependency adep(mParent->i_getMachine());
    if (FAILED(adep.rc())) return adep.rc();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (bd->mData.fActive != RT_BOOL(aActive))
    {
        m_fModified = true;
        ComObjPtr<Machine> pMachine = mParent->i_getMachine();

        bd.backup();
        bd->mData.fActive = RT_BOOL(aActive);

        // leave the lock before informing callbacks
        alock.release();

        AutoWriteLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
        pMachine->i_setModified(Machine::IsModified_USB);
        mlock.release();

        return mParent->i_onDeviceFilterChange(this, TRUE /* aActiveChanged */);
    }

    return S_OK;
}
//
// private methods
//
void Keyboard::onKeyboardLedsChange(PDMKEYBLEDS enmLeds)
{
    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    /* Save the current status. */
    menmLeds = enmLeds;

    alock.release();

    i_getParent()->i_onKeyboardLedsChange(RT_BOOL(enmLeds & PDMKEYBLEDS_NUMLOCK),
                                          RT_BOOL(enmLeds & PDMKEYBLEDS_CAPSLOCK),
                                          RT_BOOL(enmLeds & PDMKEYBLEDS_SCROLLLOCK));
}
Exemple #6
0
/**
 * Update the guest additions capabilities.
 * This is called when the guest additions capabilities change. The new capabilities
 * are given and the connector should update its internal state.
 *
 * @param   pInterface          Pointer to this interface.
 * @param   newCapabilities     New capabilities.
 * @thread  The emulation thread.
 */
DECLCALLBACK(void) vmmdevUpdateGuestCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities)
{
    PDRVMAINVMMDEV pDrv = RT_FROM_MEMBER(pInterface, DRVMAINVMMDEV, Connector);
    AssertPtr(pDrv);
    Console *pConsole = pDrv->pVMMDev->getParent();

    /* store that information in IGuest */
    Guest* pGuest = pConsole->i_getGuest();
    AssertPtrReturnVoid(pGuest);

    /*
     * Report our current capabilities (and assume none is active yet).
     */
    pGuest->i_setSupportedFeatures(newCapabilities);

    /*
     * Tell the Display, so that it can update the "supports graphics"
     * capability if the graphics card has not asserted it.
     */
    Display* pDisplay = pConsole->i_getDisplay();
    AssertPtrReturnVoid(pDisplay);
    pDisplay->i_handleUpdateVMMDevSupportsGraphics(RT_BOOL(newCapabilities & VMMDEV_GUEST_SUPPORTS_GRAPHICS));

    /*
     * Tell the console interface about the event
     * so that it can notify its consumers.
     */
    pConsole->i_onAdditionsStateChange();
}
Exemple #7
0
/**
 * Send an absolute mouse event to the VM. This requires either VirtualBox-
 * specific drivers installed in the guest or absolute pointing device
 * emulation.
 * @note the VMMDev capability change is so that the guest knows we are sending
 *       dummy events over the PS/2 device to signal the arrival of new
 *       absolute pointer data, and not pointer real movement data
 * @note all calls out of this object are made with no locks held!
 *
 * @returns COM status code
 * @param x          X position (pixel), starting from 1
 * @param y          Y position (pixel), starting from 1
 * @param dz         Z movement
 * @param fButtons   The mouse button state
 */
STDMETHODIMP Mouse::PutMouseEventAbsolute(LONG x, LONG y, LONG dz, LONG dw,
                                          LONG fButtons)
{
    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    LogRel3(("%s: x=%d, y=%d, dz=%d, dw=%d, fButtons=0x%x\n",
             __PRETTY_FUNCTION__, x, y, dz, dw, fButtons));

    int32_t xAdj, yAdj;
    uint32_t fButtonsAdj;
    bool fValid;

    /** @todo the front end should do this conversion to avoid races */
    /** @note Or maybe not... races are pretty inherent in everything done in
     *        this object and not really bad as far as I can see. */
    HRESULT rc = convertDisplayRes(x, y, &xAdj, &yAdj, &fValid);
    if (FAILED(rc)) return rc;

    fButtonsAdj = mouseButtonsToPDM(fButtons);
    /* If we are doing old-style (IRQ-less) absolute reporting to the VMM
     * device then make sure the guest is aware of it, so that it knows to
     * ignore relative movement on the PS/2 device. */
    updateVMMDevMouseCaps(VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE, 0);
    if (fValid)
    {
        rc = reportAbsEvent(xAdj, yAdj, dz, dw, fButtonsAdj,
                            RT_BOOL(  mfVMMDevGuestCaps
                                    & VMMDEV_MOUSE_NEW_PROTOCOL));

        fireMouseEvent(true, x, y, dz, dw, 0, fButtons);
    }

    return rc;
}
/**
 * Set the new patch manager enabled flag.
 *
 * @returns COM status code
 * @param   aEnable new patch manager enabled flag
 */
HRESULT MachineDebugger::setPATMEnabled(BOOL aPATMEnabled)
{
    LogFlowThisFunc(("enable=%d\n", aPATMEnabled));

#ifdef VBOX_WITH_RAW_MODE
    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (i_queueSettings())
    {
        // queue the request
        mPatmEnabledQueued = aPATMEnabled;
        return S_OK;
    }

    Console::SafeVMPtr ptrVM(mParent);
    if (FAILED(ptrVM.rc()))
        return ptrVM.rc();

    int vrc = PATMR3AllowPatching(ptrVM.rawUVM(), RT_BOOL(aPATMEnabled));
    if (RT_FAILURE(vrc))
        return setError(VBOX_E_VM_ERROR, tr("PATMR3AllowPatching returned %Rrc"), vrc);

#else  /* !VBOX_WITH_RAW_MODE */
    if (aPATMEnabled)
        return setError(VBOX_E_VM_ERROR, tr("PATM not present"), VERR_NOT_SUPPORTED);
#endif /* !VBOX_WITH_RAW_MODE */
    return S_OK;
}
HRESULT HostUSBDeviceFilter::setActive(BOOL aActive)
{
    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (bd->mData.fActive != RT_BOOL(aActive))
    {
        bd->mData.fActive = RT_BOOL(aActive);

        /* leave the lock before informing callbacks */
        alock.release();

        return mParent->i_onUSBDeviceFilterChange(this, TRUE /* aActiveChanged  */);
    }

    return S_OK;
}
Exemple #10
0
/*
 * We differentiate between a function handler for the guest and one for the host.
 */
static DECLCALLBACK(int) svcHostCall (void *,
                                      uint32_t u32Function,
                                      uint32_t cParms,
                                      VBOXHGCMSVCPARM paParms[])
{
    int rc = VINF_SUCCESS;

    LogRel2(("svcHostCall: fn = %d, cParms = %d, pparms = %d\n",
         u32Function, cParms, paParms));

    switch (u32Function)
    {
        case VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE:
        {
            LogRel2(("svcCall: VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE\n"));

            if (cParms != 1)
            {
                rc = VERR_INVALID_PARAMETER;
            }
            else if (   paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT   /* mode */
                    )
            {
                rc = VERR_INVALID_PARAMETER;
            }
            else
            {
                uint32_t u32Mode = VBOX_SHARED_CLIPBOARD_MODE_OFF;

                rc = VBoxHGCMParmUInt32Get (&paParms[0], &u32Mode);

                /* The setter takes care of invalid values. */
                vboxSvcClipboardModeSet (u32Mode);
            }
        } break;

        case VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS:
        {
            uint32_t u32Headless = g_fHeadless;

            rc = VERR_INVALID_PARAMETER;
            if (cParms != 1)
                break;
            rc = VBoxHGCMParmUInt32Get (&paParms[0], &u32Headless);
            if (RT_SUCCESS(rc))
                LogRelFlow(("svcCall: VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS, u32Headless=%u\n",
                            (unsigned) u32Headless));
            g_fHeadless = RT_BOOL(u32Headless);
        } break;

        default:
            break;
    }

    LogRelFlow(("svcHostCall: rc = %Rrc\n", rc));
    return rc;
}
/** @note Locks objects for writing! */
void StorageController::i_setBootable(BOOL fBootable)
{
    AutoCaller autoCaller(this);
    AssertComRCReturnVoid(autoCaller.rc());

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    m->bd.backup();
    m->bd->fBootable = RT_BOOL(fBootable);
}
Exemple #12
0
/**
 * [REP*] INSB/INSW/INSD
 * ES:EDI,DX[,ECX]
 *
 * @returns Strict VBox status code. Informational status codes other than the one documented
 *          here are to be treated as internal failure. Use IOM_SUCCESS() to check for success.
 * @retval  VINF_SUCCESS                Success.
 * @retval  VINF_EM_FIRST-VINF_EM_LAST  Success with some exceptions (see IOM_SUCCESS()), the
 *                                      status code must be passed on to EM.
 * @retval  VINF_IOM_R3_IOPORT_READ     Defer the read to ring-3. (R0/GC only)
 * @retval  VINF_EM_RAW_EMULATE_INSTR   Defer the read to the REM.
 * @retval  VINF_EM_RAW_GUEST_TRAP      The exception was left pending. (TRPMRaiseXcptErr)
 * @retval  VINF_TRPM_XCPT_DISPATCHED   The exception was raised and dispatched for raw-mode execution. (TRPMRaiseXcptErr)
 * @retval  VINF_EM_RESCHEDULE_REM      The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr)
 *
 * @param   pVM         The cross context VM structure.
 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
 * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure.
 * @param   pCpu        Disassembler CPU state.
 */
static VBOXSTRICTRC iomRCInterpretINS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)
{
    uint8_t cbValue = pCpu->pCurInstr->uOpcode == OP_INSB ? 1
                    : pCpu->uOpMode == DISCPUMODE_16BIT ? 2 : 4;       /* dword in both 32 & 64 bits mode */
    return IEMExecStringIoRead(pVCpu,
                               cbValue,
                               iomDisModeToIemMode((DISCPUMODE)pCpu->uCpuMode),
                               RT_BOOL(pCpu->fPrefix & (DISPREFIX_REPNE | DISPREFIX_REP)),
                               pCpu->cbInstr,
                               false /*fIoChecked*/);
}
/** Allocate (and return) a buffer for a device list in VRDP wire format,
 * and populate from a PUSBDEVICE linked list.  @a pLen takes the length of
 * the new list.
 * See @a Console::processRemoteUSBDevices for the receiving end. */
static void *buildWireListFromDevices(PUSBDEVICE pDevices, int *pLen)
{
    char *pBuf;
    unsigned cDevs, cbBuf, iCurrent;
    uint16_t iNext;
    PUSBDEVICE pCurrent;

    cDevs = countUSBDevices(pDevices);
    cbBuf = cDevs * DEV_ENTRY_SIZE + 2;
    pBuf = (char *)xmalloc(cbBuf);
    memset(pBuf, 0, cbBuf);
    for (pCurrent = pDevices, iCurrent = 0; pCurrent;
         pCurrent = pCurrent->pNext, iCurrent += iNext, --cDevs)
    {
        unsigned i, cZeros;

        AssertReturnStmt(iCurrent + DEV_ENTRY_SIZE + 2 <= cbBuf,
                         free(pBuf), NULL);
        fillWireListEntry(pBuf + iCurrent, pCurrent, &iNext);
            DevListEntry *pEntry = (DevListEntry *)(pBuf + iCurrent);
        /* Sanity tests */
        for (i = iCurrent + sizeof(DevListEntry), cZeros = 0;
             i < iCurrent + iNext; ++i)
             if (pBuf[i] == 0)
                 ++cZeros;
        AssertReturnStmt(cZeros ==   RT_BOOL(pEntry->oManufacturer)
                                   + RT_BOOL(pEntry->oProduct)
                                   + RT_BOOL(pEntry->oSerialNumber),
                         free(pBuf), NULL);
        Assert(pEntry->oManufacturer == 0 || pBuf[iCurrent + pEntry->oManufacturer] != '\0');
        Assert(pEntry->oProduct == 0 || pBuf[iCurrent + pEntry->oProduct] != '\0');
        Assert(pEntry->oSerialNumber == 0 || pBuf[iCurrent + pEntry->oSerialNumber] != '\0');
        AssertReturnStmt(cZeros == 0 || pBuf[iCurrent + iNext - 1] == '\0',
                         free(pBuf), NULL);
    }
    *pLen = iCurrent + iNext + 2;
    Assert(cDevs == 0);
    Assert(*pLen <= cbBuf);
    return pBuf;
}
bool GuestDnDResponse::isProgressCanceled(void) const
{
    BOOL fCanceled;
    if (!m_progress.isNull())
    {
        HRESULT hr = m_progress->COMGETTER(Canceled)(&fCanceled);
        AssertComRC(hr);
    }
    else
        fCanceled = TRUE;

    return RT_BOOL(fCanceled);
}
Exemple #15
0
RTR3DECL(int) RTStrmSetMode(PRTSTREAM pStream, int fBinary, int fCurrentCodeSet)
{
    AssertPtrReturn(pStream, VERR_INVALID_HANDLE);
    AssertReturn(pStream->u32Magic == RTSTREAM_MAGIC, VERR_INVALID_HANDLE);
    AssertReturn((unsigned)(fBinary + 1) <= 2, VERR_INVALID_PARAMETER);
    AssertReturn((unsigned)(fCurrentCodeSet + 1) <= 2, VERR_INVALID_PARAMETER);

    rtStrmLock(pStream);

    if (fBinary != -1)
    {
        pStream->fBinary      = RT_BOOL(fBinary);
        pStream->fRecheckMode = true;
    }

    if (fCurrentCodeSet != -1)
        pStream->fCurrentCodeSet = RT_BOOL(fCurrentCodeSet);

    rtStrmUnlock(pStream);

    return VINF_SUCCESS;
}
Exemple #16
0
VBOXDDU_DECL(int) VDDbgIoLogEventGetStart(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
                                          uint64_t *poff, size_t *pcbIo, size_t cbBuf, void *pvBuf)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
    AssertPtrReturn(pfAsync, VERR_INVALID_POINTER);
    AssertPtrReturn(poff, VERR_INVALID_POINTER);
    AssertPtrReturn(pcbIo, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START)
    {
        IoLogEntryStart Entry;
        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
        if (RT_SUCCESS(rc))
        {
            *pfAsync   = RT_BOOL(Entry.u8AsyncIo);
            *pidEvent  = RT_LE2H_U64(Entry.u64Id);
            *poff      = RT_LE2H_U64(Entry.Io.u64Off);
            *pcbIo     = RT_LE2H_U64(Entry.Io.u64IoSize);

            if (   pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_WRITE
                && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN))
            {
                /* Read data. */
                if (cbBuf < *pcbIo)
                    rc = VERR_BUFFER_OVERFLOW;
                else
                    rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + sizeof(Entry), pvBuf, *pcbIo, NULL);

                if (rc != VERR_BUFFER_OVERFLOW)
                    pIoLogger->offReadNext += *pcbIo + sizeof(Entry);
            }
            else
                pIoLogger->offReadNext += sizeof(Entry);
        }
    }
    else
        rc = VERR_INVALID_STATE;

    if (RT_SUCCESS(rc))
        pIoLogger->u32EventTypeNext = 0;

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
/**
 * Returns the current PAE flag.
 *
 * @returns COM status code
 * @param   aEnabled address of result variable
 */
HRESULT MachineDebugger::getPAEEnabled(BOOL *aPAEEnabled)
{
    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);

    Console::SafeVMPtrQuiet ptrVM(mParent);

    if (ptrVM.isOk())
    {
        uint32_t cr4;
        int rc = DBGFR3RegCpuQueryU32(ptrVM.rawUVM(), 0 /*idCpu*/,  DBGFREG_CR4, &cr4); AssertRC(rc);
        *aPAEEnabled = RT_BOOL(cr4 & X86_CR4_PAE);
    }
    else
        *aPAEEnabled = false;

    return S_OK;
}
/**
 * Loads the global configuration from registry.
 *
 * @return  DWORD       Windows error code.
 */
DWORD
VBoxCredProvProvider::LoadConfiguration(void)
{
    HKEY hKey;
    /** @todo Add some registry wrapper function(s) as soon as we got more values to retrieve. */
    DWORD dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Oracle\\VirtualBox Guest Additions\\AutoLogon",
                               0L, KEY_QUERY_VALUE, &hKey);
    if (dwRet == ERROR_SUCCESS)
    {
        DWORD dwValue;
        DWORD dwType = REG_DWORD;
        DWORD dwSize = sizeof(DWORD);

        dwRet = RegQueryValueEx(hKey, L"HandleRemoteSessions", NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
        if (   dwRet  == ERROR_SUCCESS
            && dwType == REG_DWORD
            && dwSize == sizeof(DWORD))
        {
            m_fHandleRemoteSessions = RT_BOOL(dwValue);
        }

        dwRet = RegQueryValueEx(hKey, L"LoggingEnabled", NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
        if (   dwRet  == ERROR_SUCCESS
            && dwType == REG_DWORD
            && dwSize == sizeof(DWORD))
        {
            g_dwVerbosity = 1; /* Default logging level. */
        }

        if (g_dwVerbosity) /* Do we want logging at all? */
        {
            dwRet = RegQueryValueEx(hKey, L"LoggingLevel", NULL, &dwType, (LPBYTE)&dwValue, &dwSize);
            if (   dwRet  == ERROR_SUCCESS
                && dwType == REG_DWORD
                && dwSize == sizeof(DWORD))
            {
                g_dwVerbosity = dwValue;
            }
        }

        RegCloseKey(hKey);
    }
    /* Do not report back an error here yet. */
    return ERROR_SUCCESS;
}
/**
 * Get the video mode for the first screen using the port registers.  All
 * parameters are optional
 * @returns  true if the VBE mode returned is active, false if we are in VGA
 *           mode
 * @note  If anyone else needs additional register values just extend the
 *        function with additional parameters and fix any existing callers.
 * @param  pcWidth      where to store the mode width
 * @param  pcHeight     where to store the mode height
 * @param  pcVirtWidth  where to store the mode pitch
 * @param  pcBPP        where to store the colour depth of the mode
 * @param  pfFlags      where to store the flags for the mode
 */
RTDECL(bool) VBoxVideoGetModeRegisters(uint16_t *pcWidth, uint16_t *pcHeight,
                                       uint16_t *pcVirtWidth, uint16_t *pcBPP,
                                       uint16_t *pfFlags)
{
    uint16_t fFlags;

    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
                                VBE_DISPI_INDEX_ENABLE);
    fFlags = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
    if (pcWidth)
    {
        VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
                                    VBE_DISPI_INDEX_XRES);
        *pcWidth = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
    }
    if (pcHeight)
    {
        VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
                                    VBE_DISPI_INDEX_YRES);
        *pcHeight = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
    }
    if (pcVirtWidth)
    {
        VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
                                    VBE_DISPI_INDEX_VIRT_WIDTH);
        *pcVirtWidth = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
    }
    if (pcBPP)
    {
        VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX,
                                    VBE_DISPI_INDEX_BPP);
        *pcBPP = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
    }
    if (pfFlags)
        *pfFlags = fFlags;
    return RT_BOOL(fFlags & VBE_DISPI_ENABLED);
}
STDMETHODIMP VBoxDnDDropTarget::Drop(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
    RT_NOREF(pt);
    AssertPtrReturn(pDataObject, E_INVALIDARG);
    AssertPtrReturn(pdwEffect,   E_INVALIDARG);

    LogFlowFunc(("mFormatEtc.cfFormat=%RI16 (%s), pDataObject=0x%p, grfKeyState=0x%x, x=%ld, y=%ld\n",
                 mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
                 pDataObject, grfKeyState, pt.x, pt.y));

    HRESULT hr = S_OK;

    if (mFormatEtc.cfFormat) /* Did we get a supported format yet? */
    {
        /* Make sure the data object's data format is still valid. */
        hr = pDataObject->QueryGetData(&mFormatEtc);
        AssertMsg(SUCCEEDED(hr),
                  ("Data format changed to invalid between DragEnter() and Drop(), cfFormat=%RI16 (%s), hr=%Rhrc\n",
                  mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat), hr));
    }

    int rc = VINF_SUCCESS;

    if (SUCCEEDED(hr))
    {
        STGMEDIUM stgMed;
        hr = pDataObject->GetData(&mFormatEtc, &stgMed);
        if (SUCCEEDED(hr))
        {
            /*
             * First stage: Prepare the access to the storage medium.
             *              For now we only support HGLOBAL stuff.
             */
            PVOID pvData = NULL; /** @todo Put this in an own union? */

            switch (mFormatEtc.tymed)
            {
                case TYMED_HGLOBAL:
                    pvData = GlobalLock(stgMed.hGlobal);
                    if (!pvData)
                    {
                        LogFlowFunc(("Locking HGLOBAL storage failed with %Rrc\n",
                                     RTErrConvertFromWin32(GetLastError())));
                        rc = VERR_INVALID_HANDLE;
                        hr = E_INVALIDARG; /* Set special hr for OLE. */
                    }
                    break;

                default:
                    AssertMsgFailed(("Storage medium type %RI32 supported\n",
                                     mFormatEtc.tymed));
                    rc = VERR_NOT_SUPPORTED;
                    hr = DV_E_TYMED; /* Set special hr for OLE. */
                    break;
            }

            if (RT_SUCCESS(rc))
            {
                /*
                 * Second stage: Do the actual copying of the data object's data,
                 *               based on the storage medium type.
                 */
                switch (mFormatEtc.cfFormat)
                {
                    case CF_TEXT:
                    /* Fall through is intentional. */
                    case CF_UNICODETEXT:
                    {
                        AssertPtr(pvData);
                        size_t cbSize = GlobalSize(pvData);
                        LogFlowFunc(("CF_TEXT/CF_UNICODETEXT 0x%p got %zu bytes\n", pvData, cbSize));
                        if (cbSize)
                        {
                            char *pszText = NULL;

                            rc = mFormatEtc.cfFormat == CF_TEXT
                               /* ANSI codepage -> UTF-8 */
                               ? RTStrCurrentCPToUtf8(&pszText, (char *)pvData)
                               /* Unicode  -> UTF-8 */
                               : RTUtf16ToUtf8((PCRTUTF16)pvData, &pszText);

                            if (RT_SUCCESS(rc))
                            {
                                AssertPtr(pszText);

                                size_t cbText = strlen(pszText) + 1; /* Include termination. */

                                mpvData = RTMemDup((void *)pszText, cbText);
                                mcbData = cbText;

                                RTStrFree(pszText);
                                pszText = NULL;
                            }
                        }

                        break;
                    }

                    case CF_HDROP:
                    {
                        AssertPtr(pvData);

                        /* Convert to a string list, separated by \r\n. */
                        DROPFILES *pDropFiles = (DROPFILES *)pvData;
                        AssertPtr(pDropFiles);
                        bool fUnicode = RT_BOOL(pDropFiles->fWide);

                        /* Get the offset of the file list. */
                        Assert(pDropFiles->pFiles >= sizeof(DROPFILES));
                        /* Note: This is *not* pDropFiles->pFiles! DragQueryFile only
                         *       will work with the plain storage medium pointer! */
                        HDROP hDrop = (HDROP)(pvData);

                        /* First, get the file count. */
                        /** @todo Does this work on Windows 2000 / NT4? */
                        char *pszFiles = NULL;
                        uint32_t cchFiles = 0;
                        UINT cFiles = DragQueryFile(hDrop, UINT32_MAX /* iFile */,
                                                    NULL /* lpszFile */, 0 /* cchFile */);
                        LogFlowFunc(("CF_HDROP got %RU16 file(s)\n", cFiles));

                        for (UINT i = 0; i < cFiles; i++)
                        {
                            UINT cch = DragQueryFile(hDrop, i /* File index */,
                                                     NULL /* Query size first */,
                                                     0 /* cchFile */);
                            Assert(cch);

                            if (RT_FAILURE(rc))
                                break;

                            char *pszFile = NULL; /* UTF-8 version. */
                            UINT cchFile = 0;
                            if (fUnicode)
                            {
                                /* Allocate enough space (including terminator). */
                                WCHAR *pwszFile = (WCHAR *)RTMemAlloc((cch + 1) * sizeof(WCHAR));
                                if (pwszFile)
                                {
                                    cchFile = DragQueryFileW(hDrop, i /* File index */,
                                                             pwszFile, cch + 1 /* Include terminator */);
                                    AssertMsg(cchFile == cch, ("cchCopied (%RU16) does not match cchFile (%RU16)\n",
                                                               cchFile, cch));
                                    rc = RTUtf16ToUtf8(pwszFile, &pszFile);
                                    AssertRC(rc);

                                    RTMemFree(pwszFile);
                                }
                                else
                                    rc = VERR_NO_MEMORY;
                            }
                            else /* ANSI */
                            {
                                /* Allocate enough space (including terminator). */
                                pszFile = (char *)RTMemAlloc((cch + 1) * sizeof(char));
                                if (pszFile)
                                {
                                    cchFile = DragQueryFileA(hDrop, i /* File index */,
                                                             pszFile, cchFile + 1 /* Include terminator */);
                                    AssertMsg(cchFile == cch, ("cchCopied (%RU16) does not match cchFile (%RU16)\n",
                                                               cchFile, cch));
                                }
                                else
                                    rc = VERR_NO_MEMORY;
                            }

                            if (RT_SUCCESS(rc))
                            {
                                LogFlowFunc(("\tFile: %s (cchFile=%RU32)\n", pszFile, cchFile));
                                rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
                                                     pszFile, cchFile);
                                if (RT_SUCCESS(rc))
                                    cchFiles += cchFile;
                            }

                            if (pszFile)
                                RTStrFree(pszFile);

                            if (RT_FAILURE(rc))
                                break;

                            /* Add separation between filenames.
                             * Note: Also do this for the last element of the list. */
                            rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
                                                 "\r\n", 2 /* Bytes */);
                            if (RT_SUCCESS(rc))
                                cchFiles += 2; /* Include \r\n */
                        }

                        if (RT_SUCCESS(rc))
                        {
                            cchFiles += 1; /* Add string termination. */
                            uint32_t cbFiles = cchFiles * sizeof(char);

                            LogFlowFunc(("cFiles=%u, cchFiles=%RU32, cbFiles=%RU32, pszFiles=0x%p\n",
                                         cFiles, cchFiles, cbFiles, pszFiles));

                            /* Translate the list into URI elements. */
                            DnDURIList lstURI;
                            rc = lstURI.AppendNativePathsFromList(pszFiles, cbFiles,
                                                                  DNDURILIST_FLAGS_ABSOLUTE_PATHS);
                            if (RT_SUCCESS(rc))
                            {
                                RTCString strRoot = lstURI.RootToString();
                                size_t cbRoot = strRoot.length() + 1; /* Include termination */

                                mpvData = RTMemAlloc(cbRoot);
                                if (mpvData)
                                {
                                    memcpy(mpvData, strRoot.c_str(), cbRoot);
                                    mcbData = cbRoot;
                                }
                                else
                                    rc = VERR_NO_MEMORY;
                            }
                        }

                        LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n",
                                     rc, pszFiles, cFiles, cchFiles));

                        if (pszFiles)
                            RTStrFree(pszFiles);
                        break;
                    }

                    default:
                        /* Note: Should not happen due to the checks done in DragEnter(). */
                        AssertMsgFailed(("Format of type %RI16 (%s) not supported\n",
                                         mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat)));
                        hr = DV_E_CLIPFORMAT; /* Set special hr for OLE. */
                        break;
                }

                /*
                 * Third stage: Unlock + release access to the storage medium again.
                 */
                switch (mFormatEtc.tymed)
                {
                    case TYMED_HGLOBAL:
                        GlobalUnlock(stgMed.hGlobal);
                        break;

                    default:
                        AssertMsgFailed(("Really should not happen -- see init stage!\n"));
                        break;
                }
            }

            /* Release storage medium again. */
            ReleaseStgMedium(&stgMed);

            /* Signal waiters. */
            mDroppedRc = rc;
            RTSemEventSignal(hEventDrop);
        }
    }

    if (RT_SUCCESS(rc))
    {
        /* Note: pt is not used since we don't need to differentiate within our
         *       proxy window. */
        *pdwEffect = VBoxDnDDropTarget::GetDropEffect(grfKeyState, *pdwEffect);
    }
    else
        *pdwEffect = DROPEFFECT_NONE;

    if (mpWndParent)
        mpWndParent->hide();

    LogFlowFunc(("Returning with hr=%Rhrc (%Rrc), mFormatEtc.cfFormat=%RI16 (%s), *pdwEffect=%RI32\n",
                 hr, rc, mFormatEtc.cfFormat, VBoxDnDDataObject::ClipboardFormatToString(mFormatEtc.cfFormat),
                 *pdwEffect));

    return hr;
}
int vbsfPathGuestToHost(SHFLCLIENTDATA *pClient, SHFLROOT hRoot,
                        PCSHFLSTRING pGuestString, uint32_t cbGuestString,
                        char **ppszHostPath, uint32_t *pcbHostPathRoot,
                        uint32_t fu32Options,
                        uint32_t *pfu32PathFlags)
{
#ifdef VBOX_STRICT
    /*
     * Check that the pGuestPath has correct size and encoding.
     */
    if (ShflStringIsValidIn(pGuestString, cbGuestString, RT_BOOL(pClient->fu32Flags & SHFL_CF_UTF8)) == false)
    {
        LogFunc(("Invalid input string\n"));
        return VERR_INTERNAL_ERROR;
    }
#else
    NOREF(cbGuestString);
#endif

    /*
     * Resolve the root handle into a string.
     */
    uint32_t cbRootLen = 0;
    const char *pszRoot = NULL;
    int rc = vbsfMappingsQueryHostRootEx(hRoot, &pszRoot, &cbRootLen);
    if (RT_FAILURE(rc))
    {
        LogFunc(("invalid root\n"));
        return rc;
    }

    AssertReturn(cbRootLen > 0, VERR_INTERNAL_ERROR_2); /* vbsfMappingsQueryHostRootEx ensures this. */

    /*
     * Get the UTF8 string with the relative path provided by the guest.
     * If guest uses UTF-16 then convert it to UTF-8.
     */
    uint32_t    cbGuestPath = 0;        /* Shut up MSC */
    const char *pchGuestPath = NULL;    /* Ditto. */
    char *pchGuestPathAllocated = NULL; /* Converted from UTF-16. */
    if (BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8))
    {
        /* UTF-8 */
        cbGuestPath = pGuestString->u16Length;
        pchGuestPath = pGuestString->String.ach;
    }
    else
    {
        /* UTF-16 */

#ifdef RT_OS_DARWIN /* Misplaced hack! See todo! */
        uint32_t cwcSrc  = 0;
        PRTUTF16 pwszSrc = NULL;
        rc = vbsfNormalizeStringDarwin(&pGuestString->String.ucs2[0],
                                       pGuestString->u16Length / sizeof(RTUTF16),
                                       &pwszSrc, &cwcSrc);
#else
        uint32_t  const cwcSrc  = pGuestString->u16Length / sizeof(RTUTF16);
        PCRTUTF16 const pwszSrc = &pGuestString->String.ucs2[0];
#endif

        if (RT_SUCCESS(rc))
        {
            size_t cbPathAsUtf8 = RTUtf16CalcUtf8Len(pwszSrc);
            if (cbPathAsUtf8 >= cwcSrc)
            {
                /* Allocate buffer that will be able to contain the converted UTF-8 string. */
                pchGuestPathAllocated = (char *)RTMemAlloc(cbPathAsUtf8 + 1);
                if (RT_LIKELY(pchGuestPathAllocated != NULL))
                {
                    if (RT_LIKELY(cbPathAsUtf8))
                    {
                        size_t cchActual;
                        char *pszDst = pchGuestPathAllocated;
                        rc = RTUtf16ToUtf8Ex(pwszSrc, cwcSrc, &pszDst, cbPathAsUtf8 + 1, &cchActual);
                        AssertRC(rc);
                        AssertStmt(RT_FAILURE(rc) || cchActual == cbPathAsUtf8, rc = VERR_INTERNAL_ERROR_4);
                        Assert(strlen(pszDst) == cbPathAsUtf8);
                    }

                    if (RT_SUCCESS(rc))
                    {
                        /* Terminate the string. */
                        pchGuestPathAllocated[cbPathAsUtf8] = '\0';

                        cbGuestPath = (uint32_t)cbPathAsUtf8; Assert(cbGuestPath == cbPathAsUtf8);
                        pchGuestPath = pchGuestPathAllocated;
                    }
                }
                else
                {
                    rc = VERR_NO_MEMORY;
                }
            }
            else
            {
                AssertFailed();
                rc = VERR_INTERNAL_ERROR_3;
            }

#ifdef RT_OS_DARWIN
            RTMemFree(pwszSrc);
#endif
        }
    }

    char *pszFullPath = NULL;

    if (RT_SUCCESS(rc))
    {
        LogFlowFunc(("Root %s path %.*s\n", pszRoot, cbGuestPath, pchGuestPath));

        /*
         * Allocate enough memory to build the host full path from the root and the relative path.
         */
        const uint32_t cbFullPathAlloc = cbRootLen + 1 + cbGuestPath + 1; /* root + possible_slash + relative + 0 */
        pszFullPath = (char *)RTMemAlloc(cbFullPathAlloc);
        if (RT_LIKELY(pszFullPath != NULL))
        {
            /* Buffer for the verified guest path. */
            char *pchVerifiedPath = (char *)RTMemAlloc(cbGuestPath + 1);
            if (RT_LIKELY(pchVerifiedPath != NULL))
            {
                /* Init the pointer for the guest relative path. */
                uint32_t cbSrc = cbGuestPath;
                const char *pchSrc = pchGuestPath;

                /* Strip leading delimiters from the path the guest specified. */
                while (   cbSrc > 0
                       && *pchSrc == pClient->PathDelimiter)
                {
                    ++pchSrc;
                    --cbSrc;
                }

                /*
                 * Iterate the guest path components, verify each of them replacing delimiters with the host slash.
                 */
                char *pchDst = pchVerifiedPath;
                bool fLastComponentHasWildcard = false;
                for (; cbSrc > 0; --cbSrc, ++pchSrc)
                {
                    if (RT_LIKELY(*pchSrc != pClient->PathDelimiter))
                    {
                        if (RT_LIKELY(vbsfPathIsValidNameChar(*pchSrc)))
                        {
                            if (pfu32PathFlags && vbsfPathIsWildcardChar(*pchSrc))
                            {
                                fLastComponentHasWildcard = true;
                            }

                            *pchDst++ = *pchSrc;
                        }
                        else
                        {
                            rc = VERR_INVALID_NAME;
                            break;
                        }
                    }
                    else
                    {
                        /* Replace with the host slash. */
                        *pchDst++ = RTPATH_SLASH;

                        if (pfu32PathFlags && fLastComponentHasWildcard && cbSrc > 1)
                        {
                            /* Processed component has a wildcard and there are more characters in the path. */
                            *pfu32PathFlags |= VBSF_F_PATH_HAS_WILDCARD_IN_PREFIX;
                        }
                        fLastComponentHasWildcard = false;
                    }
                }

                if (RT_SUCCESS(rc))
                {
                    *pchDst++ = 0;

                    /* Construct the full host path removing '.' and '..'. */
                    rc = vbsfPathAbs(pszRoot, pchVerifiedPath, pszFullPath, cbFullPathAlloc);
                    if (RT_SUCCESS(rc))
                    {
                        if (pfu32PathFlags && fLastComponentHasWildcard)
                        {
                            *pfu32PathFlags |= VBSF_F_PATH_HAS_WILDCARD_IN_LAST;
                        }

                        /* Check if the full path is still within the shared folder. */
                        if (fu32Options & VBSF_O_PATH_CHECK_ROOT_ESCAPE)
                        {
                            if (!RTPathStartsWith(pszFullPath, pszRoot))
                            {
                                rc = VERR_INVALID_NAME;
                            }
                        }

                        if (RT_SUCCESS(rc))
                        {
                            /*
                             * If the host file system is case sensitive and the guest expects
                             * a case insensitive fs, then correct the path components casing.
                             */
                            if (    vbsfIsHostMappingCaseSensitive(hRoot)
                                && !vbsfIsGuestMappingCaseSensitive(hRoot))
                            {
                                const bool fWildCard = RT_BOOL(fu32Options & VBSF_O_PATH_WILDCARD);
                                const bool fPreserveLastComponent = RT_BOOL(fu32Options & VBSF_O_PATH_PRESERVE_LAST_COMPONENT);
                                rc = vbsfCorrectPathCasing(pClient, pszFullPath, strlen(pszFullPath),
                                                           fWildCard, fPreserveLastComponent);
                            }

                            if (RT_SUCCESS(rc))
                            {
                               LogFlowFunc(("%s\n", pszFullPath));

                               /* Return the full host path. */
                               *ppszHostPath = pszFullPath;

                               if (pcbHostPathRoot)
                               {
                                   /* Return the length of the root path without the trailing slash. */
                                   *pcbHostPathRoot = RTPATH_IS_SLASH(pszFullPath[cbRootLen - 1]) ?
                                                          cbRootLen - 1 : /* pszRoot already had the trailing slash. */
                                                          cbRootLen; /* pszRoot did not have the trailing slash. */
                               }
                            }
                        }
                    }
                    else
                    {
                        LogFunc(("vbsfPathAbs %Rrc\n", rc));
                    }
                }

                RTMemFree(pchVerifiedPath);
            }
            else
            {
                rc = VERR_NO_MEMORY;
            }
        }
        else
        {
            rc = VERR_NO_MEMORY;
        }
    }

    /*
     * Cleanup.
     */
    RTMemFree(pchGuestPathAllocated);

    if (RT_SUCCESS(rc))
    {
        return rc;
    }

    /*
     * Cleanup on failure.
     */
    RTMemFree(pszFullPath);

    LogFunc(("%Rrc\n", rc));
    return rc;
}
                break;
            }
            fComplainedAMD64 = true;
        }
    }
}

#undef Bs3TestDoModes
BS3_MODE_DEF(void, Bs3TestDoModes,(PCBS3TESTMODEENTRY paEntries, size_t cEntries))
{
    bool const      fVerbose         = true;
    bool const      fDoV86Modes      = true;
    bool const      fDoWeirdV86Modes = true;
    uint16_t const  uCpuDetected  = g_uBs3CpuDetected;
    uint8_t const   bCpuType      = uCpuDetected & BS3CPU_TYPE_MASK;
    bool const      fHavePae      = RT_BOOL(uCpuDetected & BS3CPU_F_PAE);
    bool const      fHaveLongMode = RT_BOOL(uCpuDetected & BS3CPU_F_LONG_MODE);
    unsigned        i;

#if 1 /* debug. */
    Bs3Printf("Bs3TestDoModes: uCpuDetected=%#x fHavePae=%d fHaveLongMode=%d\n", uCpuDetected, fHavePae, fHaveLongMode);
#endif
    bs3TestWarnAboutSkippedModes(paEntries, cEntries, bCpuType, fHavePae, fHaveLongMode);

    /*
     * The real run.
     */
    for (i = 0; i < cEntries; i++)
    {
        const char *pszFmtStr = "Error #%u (%#x) in %s!\n";
        bool        fSkipped  = true;
/*
 * Read from so's socket into sb_snd, updating all relevant sbuf fields
 * NOTE: This will only be called if it is select()ed for reading, so
 * a read() of 0 (or less) means it's disconnected
 */
int
soread(PNATState pData, struct socket *so)
{
    int n, nn, lss, total;
    struct sbuf *sb = &so->so_snd;
    u_int len = sb->sb_datalen - sb->sb_cc;
    struct iovec iov[2];
    int mss = so->so_tcpcb->t_maxseg;
    int sockerr;

    STAM_PROFILE_START(&pData->StatIOread, a);
    STAM_COUNTER_RESET(&pData->StatIORead_in_1);
    STAM_COUNTER_RESET(&pData->StatIORead_in_2);

    QSOCKET_LOCK(tcb);
    SOCKET_LOCK(so);
    QSOCKET_UNLOCK(tcb);

    LogFlow(("soread: so = %R[natsock]\n", so));
    Log2(("%s: so = %R[natsock] so->so_snd = %R[sbuf]\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, so, sb));

    /*
     * No need to check if there's enough room to read.
     * soread wouldn't have been called if there weren't
     */

    len = sb->sb_datalen - sb->sb_cc;

    iov[0].iov_base = sb->sb_wptr;
    iov[1].iov_base = 0;
    iov[1].iov_len  = 0;
    if (sb->sb_wptr < sb->sb_rptr)
    {
        iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
        /* Should never succeed, but... */
        if (iov[0].iov_len > len)
            iov[0].iov_len = len;
        if (iov[0].iov_len > mss)
            iov[0].iov_len -= iov[0].iov_len%mss;
        n = 1;
    }
    else
    {
        iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
        /* Should never succeed, but... */
        if (iov[0].iov_len > len)
            iov[0].iov_len = len;
        len -= iov[0].iov_len;
        if (len)
        {
            iov[1].iov_base = sb->sb_data;
            iov[1].iov_len = sb->sb_rptr - sb->sb_data;
            if (iov[1].iov_len > len)
                iov[1].iov_len = len;
            total = iov[0].iov_len + iov[1].iov_len;
            if (total > mss)
            {
                lss = total % mss;
                if (iov[1].iov_len > lss)
                {
                    iov[1].iov_len -= lss;
                    n = 2;
                }
                else
                {
                    lss -= iov[1].iov_len;
                    iov[0].iov_len -= lss;
                    n = 1;
                }
            }
            else
                n = 2;
        }
        else
        {
            if (iov[0].iov_len > mss)
                iov[0].iov_len -= iov[0].iov_len%mss;
            n = 1;
        }
    }

#ifdef HAVE_READV
    nn = readv(so->s, (struct iovec *)iov, n);
#else
    nn = recv(so->s, iov[0].iov_base, iov[0].iov_len, (so->so_tcpcb->t_force? MSG_OOB:0));
#endif
    if (nn < 0)
        sockerr = errno; /* save it, as it may be clobbered by logging */
    else
        sockerr = 0;

    Log2(("%s: read(1) nn = %d bytes\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, nn));
    Log2(("%s: so = %R[natsock] so->so_snd = %R[sbuf]\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, so, sb));
    if (nn <= 0)
    {
#ifdef RT_OS_WINDOWS
        /*
         * Windows reports ESHUTDOWN after SHUT_RD (SD_RECEIVE)
         * instead of just returning EOF indication.
         */
        if (nn < 0 && sockerr == ESHUTDOWN)
        {
            nn = 0;
            sockerr = 0;
        }
#endif

        if (nn == 0) /* XXX: should this be inside #if defined(RT_OS_WINDOWS)? */
        {
            /*
             * Special case for WSAEnumNetworkEvents: If we receive 0 bytes that
             * _could_ mean that the connection is closed. But we will receive an
             * FD_CLOSE event later if the connection was _really_ closed. With
             * www.youtube.com I see this very often. Closing the socket too early
             * would be dangerous.
             */
            int status;
            unsigned long pending = 0;
            status = ioctlsocket(so->s, FIONREAD, &pending);
            if (status < 0)
                Log(("NAT:%s: error in WSAIoctl: %d\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, errno));
            if (pending != 0)
            {
                SOCKET_UNLOCK(so);
                STAM_PROFILE_STOP(&pData->StatIOread, a);
                return 0;
            }
        }

        if (   nn < 0
            && soIgnorableErrorCode(sockerr))
        {
            SOCKET_UNLOCK(so);
            STAM_PROFILE_STOP(&pData->StatIOread, a);
            return 0;
        }
        else
        {
            int fUninitializedTemplate = 0;
            int shuterr;

            fUninitializedTemplate = RT_BOOL((   sototcpcb(so)
                                              && (  sototcpcb(so)->t_template.ti_src.s_addr == INADDR_ANY
                                                 || sototcpcb(so)->t_template.ti_dst.s_addr == INADDR_ANY)));
            /* nn == 0 means peer has performed an orderly shutdown */
            Log2(("%s: disconnected, nn = %d, errno = %d (%s)\n",
                  RT_GCC_EXTENSION __PRETTY_FUNCTION__, nn, sockerr, strerror(sockerr)));

            shuterr = sofcantrcvmore(so);
            if (!sockerr && !shuterr && !fUninitializedTemplate)
                tcp_sockclosed(pData, sototcpcb(so));
            else
            {
                LogRel2(("NAT: sockerr %d, shuterr %d - %R[natsock]\n", sockerr, shuterr, so));
                tcp_drop(pData, sototcpcb(so), sockerr);
            }
            SOCKET_UNLOCK(so);
            STAM_PROFILE_STOP(&pData->StatIOread, a);
            return -1;
        }
    }
    STAM_STATS(
        if (n == 1)
        {
            STAM_COUNTER_INC(&pData->StatIORead_in_1);
            STAM_COUNTER_ADD(&pData->StatIORead_in_1_bytes, nn);
        }
        else
        {
            STAM_COUNTER_INC(&pData->StatIORead_in_2);
            STAM_COUNTER_ADD(&pData->StatIORead_in_2_1st_bytes, nn);
        }
    );
static int rtCrPkcs7SignedData_CheckSanityExtra(PCRTCRPKCS7SIGNEDDATA pSignedData, uint32_t fFlags,
                                                PRTERRINFO pErrInfo, const char *pszErrorTag)
{
    bool const fAuthenticode = RT_BOOL(fFlags & RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE);

    //RTAsn1Dump(&pSignedData->SeqCore.Asn1Core, 0, 0, RTAsn1DumpStrmPrintfV, g_pStdOut);

    if (   RTAsn1Integer_UnsignedCompareWithU32(&pSignedData->Version, RTCRPKCS7SIGNEDDATA_V1) != 0
        && RTAsn1Integer_UnsignedCompareWithU32(&pSignedData->Version, RTCRPKCS7SIGNEDDATA_V3) != 0
        && RTAsn1Integer_UnsignedCompareWithU32(&pSignedData->Version, RTCRPKCS7SIGNEDDATA_V4) != 0
        && RTAsn1Integer_UnsignedCompareWithU32(&pSignedData->Version, RTCRPKCS7SIGNEDDATA_V5) != 0)
        return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_SIGNED_DATA_VERSION, "SignedData version is %llu, expected %u",
                             pSignedData->Version.uValue.u, RTCRPKCS7SIGNEDDATA_V1);

    /*
     * DigestAlgorithms.
     */
    if (pSignedData->DigestAlgorithms.cItems == 0) /** @todo this might be too strict */
        return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_SIGNED_DATA_NO_DIGEST_ALGOS, "SignedData.DigestAlgorithms is empty");
    if (pSignedData->DigestAlgorithms.cItems != 1 && fAuthenticode)
        return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_NOT_EXACTLY_ONE_DIGEST_ALGO,
                             "SignedData.DigestAlgorithms has more than one algorithm (%u)",
                             pSignedData->DigestAlgorithms.cItems);

    if (fFlags & RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH)
        for (uint32_t i = 0; i < pSignedData->DigestAlgorithms.cItems; i++)
        {
            if (RTCrX509AlgorithmIdentifier_QueryDigestType(&pSignedData->DigestAlgorithms.paItems[i]) == RTDIGESTTYPE_INVALID)
                return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_UNKNOWN_DIGEST_ALGORITHM,
                                     "SignedData.DigestAlgorithms[%i] is not known: %s",
                                     i, pSignedData->DigestAlgorithms.paItems[i].Algorithm.szObjId);
            if (pSignedData->DigestAlgorithms.paItems[i].Parameters.enmType != RTASN1TYPE_NULL)
                return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_PARAMS_NOT_IMPL,
                                     "SignedData.DigestAlgorithms[%i] has parameters: tag=%u",
                                     i, pSignedData->DigestAlgorithms.paItems[i].Parameters.u.Core.uTag);
        }

    /*
     * Certificates.
     */
    if (   (fFlags & RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT)
        && pSignedData->Certificates.cItems == 0)
        return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_NO_CERTIFICATES,
                            "SignedData.Certifcates is empty, expected at least one certificate");

    /*
     * Crls.
     */
    if (fAuthenticode && RTAsn1Core_IsPresent(&pSignedData->Crls))
        return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_EXPECTED_NO_CRLS,
                            "SignedData.Crls is not empty as expected for authenticode.");
    /** @todo check Crls when they become important. */

    /*
     * SignerInfos.
     */
    if (pSignedData->SignerInfos.cItems == 0)
        return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_NO_SIGNER_INFOS, "SignedData.SignerInfos is empty?");
    if (fAuthenticode && pSignedData->SignerInfos.cItems != 1)
        return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_EXPECTED_ONE_SIGNER_INFO,
                             "SignedData.SignerInfos should have one entry for authenticode: %u",
                             pSignedData->SignerInfos.cItems);

    for (uint32_t i = 0; i < pSignedData->SignerInfos.cItems; i++)
    {
        PCRTCRPKCS7SIGNERINFO pSignerInfo = &pSignedData->SignerInfos.paItems[i];

        if (RTAsn1Integer_UnsignedCompareWithU32(&pSignerInfo->Version, RTCRPKCS7SIGNERINFO_V1) != 0)
            return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_SIGNER_INFO_VERSION,
                                 "SignedData.SignerInfos[%u] version is %llu, expected %u",
                                 pSignerInfo->Version.uValue.u, RTCRPKCS7SIGNERINFO_V1);

        /* IssuerAndSerialNumber. */
        int rc = RTCrX509Name_CheckSanity(&pSignerInfo->IssuerAndSerialNumber.Name, 0, pErrInfo,
                                          "SignedData.SignerInfos[#].IssuerAndSerialNumber.Name");
        if (RT_FAILURE(rc))
            return rc;

        if (pSignerInfo->IssuerAndSerialNumber.SerialNumber.Asn1Core.cb == 0)
            return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_SIGNER_INFO_NO_ISSUER_SERIAL_NO,
                                 "SignedData.SignerInfos[%u].IssuerAndSerialNumber.SerialNumber is missing (zero length)", i);

        PCRTCRX509CERTIFICATE pCert;
        pCert = RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber(&pSignedData->Certificates,
                                                                    &pSignerInfo->IssuerAndSerialNumber.Name,
                                                                    &pSignerInfo->IssuerAndSerialNumber.SerialNumber);
        if (!pCert && (fFlags & RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT))
            return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_SIGNER_CERT_NOT_SHIPPED,
                                 "SignedData.SignerInfos[%u].IssuerAndSerialNumber not found in T0.Certificates", i);

        /* DigestAlgorithm */
        uint32_t j = 0;
        while (   j < pSignedData->DigestAlgorithms.cItems
               && RTCrX509AlgorithmIdentifier_Compare(&pSignedData->DigestAlgorithms.paItems[j],
                                                      &pSignerInfo->DigestAlgorithm) != 0)
            j++;
        if (j >= pSignedData->DigestAlgorithms.cItems)
            return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_ALGO_NOT_FOUND_IN_LIST,
                                 "SignedData.SignerInfos[%u].DigestAlgorithm (%s) not found in SignedData.DigestAlgorithms",
                                 i, pSignerInfo->DigestAlgorithm.Algorithm.szObjId);

        /* Digest encryption algorithm. */
#if 0  /** @todo Unimportant: Seen timestamp signatures specifying pkcs1-Sha256WithRsaEncryption in SignerInfo and just RSA in the certificate.  Figure out how to compare the two. */
        if (   pCert
            && RTCrX509AlgorithmIdentifier_Compare(&pSignerInfo->DigestEncryptionAlgorithm,
                                                   &pCert->TbsCertificate.SubjectPublicKeyInfo.Algorithm) != 0)
            return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_SIGNER_INFO_DIGEST_ENCRYPT_MISMATCH,
                                 "SignedData.SignerInfos[%u].DigestEncryptionAlgorithm (%s) mismatch with certificate (%s)",
                                 i, pSignerInfo->DigestEncryptionAlgorithm.Algorithm.szObjId,
                                 pCert->TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm.szObjId);
#endif

        /* Authenticated attributes we know. */
        if (RTCrPkcs7Attributes_IsPresent(&pSignerInfo->AuthenticatedAttributes))
        {
            bool fFoundContentInfo   = false;
            bool fFoundMessageDigest = false;
            for (j = 0; j < pSignerInfo->AuthenticatedAttributes.cItems; j++)
            {
                PCRTCRPKCS7ATTRIBUTE pAttrib = &pSignerInfo->AuthenticatedAttributes.paItems[j];
                if (RTAsn1ObjId_CompareWithString(&pAttrib->Type, RTCR_PKCS9_ID_CONTENT_TYPE_OID) == 0)
                {
                    if (fFoundContentInfo)
                        return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_MISSING_CONTENT_TYPE_ATTRIB,
                                            "Multiple authenticated content-type attributes.");
                    fFoundContentInfo = true;
                    AssertReturn(pAttrib->enmType == RTCRPKCS7ATTRIBUTETYPE_OBJ_IDS, VERR_INTERNAL_ERROR_3);
                    if (pAttrib->uValues.pObjIds->cItems != 1)
                        return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_BAD_CONTENT_TYPE_ATTRIB,
                                             "Expected exactly one value for content-type attrib, found: %u",
                                             pAttrib->uValues.pObjIds->cItems);
                }
                else if (RTAsn1ObjId_CompareWithString(&pAttrib->Type, RTCR_PKCS9_ID_MESSAGE_DIGEST_OID) == 0)
                {
                    if (fFoundMessageDigest)
                        return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_MISSING_MESSAGE_DIGEST_ATTRIB,
                                            "Multiple authenticated message-digest attributes.");
                    fFoundMessageDigest = true;
                    AssertReturn(pAttrib->enmType == RTCRPKCS7ATTRIBUTETYPE_OCTET_STRINGS, VERR_INTERNAL_ERROR_3);
                    if (pAttrib->uValues.pOctetStrings->cItems != 1)
                        return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_BAD_CONTENT_TYPE_ATTRIB,
                                             "Expected exactly one value for message-digest attrib, found: %u",
                                             pAttrib->uValues.pOctetStrings->cItems);
                }
                else
                    AssertReturn(pAttrib->enmType == RTCRPKCS7ATTRIBUTETYPE_UNKNOWN, VERR_INTERNAL_ERROR_3);
            }

            if (!fFoundContentInfo)
                return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_MISSING_CONTENT_TYPE_ATTRIB,
                                    "Missing authenticated content-type attribute.");
            if (!fFoundMessageDigest)
                return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_MISSING_MESSAGE_DIGEST_ATTRIB,
                                    "Missing authenticated message-digest attribute.");
        }
    }

    return VINF_SUCCESS;
}
Exemple #25
0
/**
 * MSR write handler for Hyper-V.
 *
 * @returns Strict VBox status code like CPUMSetGuestMsr().
 * @retval  VINF_CPUM_R3_MSR_WRITE
 * @retval  VERR_CPUM_RAISE_GP_0
 *
 * @param   pVCpu       Pointer to the VMCPU.
 * @param   idMsr       The MSR being written.
 * @param   pRange      The range this MSR belongs to.
 * @param   uRawValue   The raw value with the ignored bits not masked.
 */
VMM_INT_DECL(VBOXSTRICTRC) gimHvWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uRawValue)
{
    NOREF(pRange);
    PVM    pVM = pVCpu->CTX_SUFF(pVM);
    PGIMHV pHv = &pVM->gim.s.u.Hv;

    switch (idMsr)
    {
        case MSR_GIM_HV_TPR:
            PDMApicWriteMSR(pVM, pVCpu->idCpu, 0x80, uRawValue);
            return VINF_SUCCESS;

        case MSR_GIM_HV_EOI:
            PDMApicWriteMSR(pVM, pVCpu->idCpu, 0x0B, uRawValue);
            return VINF_SUCCESS;

        case MSR_GIM_HV_ICR:
            PDMApicWriteMSR(pVM, pVCpu->idCpu, 0x30, uRawValue);
            return VINF_SUCCESS;

        case MSR_GIM_HV_GUEST_OS_ID:
        {
#ifndef IN_RING3
            return VINF_CPUM_R3_MSR_WRITE;
#else
            /* Disable the hypercall-page if 0 is written to this MSR. */
            if (!uRawValue)
            {
                gimR3HvDisableHypercallPage(pVM);
                pHv->u64HypercallMsr &= ~MSR_GIM_HV_HYPERCALL_ENABLE_BIT;
            }
            else
            {
                LogRel(("GIM: HyperV: Guest OS reported ID %#RX64\n", uRawValue));
                LogRel(("GIM: HyperV: Open-source=%RTbool Vendor=%#x OS=%#x (%s) Major=%u Minor=%u ServicePack=%u Build=%u\n",
                        MSR_GIM_HV_GUEST_OS_ID_IS_OPENSOURCE(uRawValue),   MSR_GIM_HV_GUEST_OS_ID_VENDOR(uRawValue),
                        MSR_GIM_HV_GUEST_OS_ID_OS_VARIANT(uRawValue),      gimHvGetGuestOsIdVariantName(uRawValue),
                        MSR_GIM_HV_GUEST_OS_ID_MAJOR_VERSION(uRawValue),   MSR_GIM_HV_GUEST_OS_ID_MINOR_VERSION(uRawValue),
                        MSR_GIM_HV_GUEST_OS_ID_SERVICE_VERSION(uRawValue), MSR_GIM_HV_GUEST_OS_ID_BUILD(uRawValue)));
            }
            pHv->u64GuestOsIdMsr = uRawValue;
            return VINF_SUCCESS;
#endif /* IN_RING3 */
        }

        case MSR_GIM_HV_HYPERCALL:
        {
#ifndef IN_RING3
            return VINF_CPUM_R3_MSR_WRITE;
#else  /* IN_RING3 */
            /*
             * For now ignore writes to the hypercall MSR (i.e. keeps it disabled).
             * This is required to boot FreeBSD 10.1 (with Hyper-V enabled ofc),
             * see @bugref{7270#c116}.
             */
            return VINF_SUCCESS;
# if 0
            /* First, update all but the hypercall enable bit. */
            pHv->u64HypercallMsr = (uRawValue & ~MSR_GIM_HV_HYPERCALL_ENABLE_BIT);

            /* Hypercalls can only be enabled when the guest has set the Guest-OS Id Msr. */
            bool fEnable = RT_BOOL(uRawValue & MSR_GIM_HV_HYPERCALL_ENABLE_BIT);
            if (   fEnable
                && !pHv->u64GuestOsIdMsr)
            {
                return VINF_SUCCESS;
            }

            /* Is the guest disabling the hypercall-page? Allow it regardless of the Guest-OS Id Msr. */
            if (!fEnable)
            {
                gimR3HvDisableHypercallPage(pVM);
                pHv->u64HypercallMsr = uRawValue;
                return VINF_SUCCESS;
            }

            /* Enable the hypercall-page. */
            RTGCPHYS GCPhysHypercallPage = MSR_GIM_HV_HYPERCALL_GUEST_PFN(uRawValue) << PAGE_SHIFT;
            int rc = gimR3HvEnableHypercallPage(pVM, GCPhysHypercallPage);
            if (RT_SUCCESS(rc))
            {
                pHv->u64HypercallMsr = uRawValue;
                return VINF_SUCCESS;
            }

            return VERR_CPUM_RAISE_GP_0;
# endif
#endif /* IN_RING3 */
        }

        case MSR_GIM_HV_REF_TSC:
        {
#ifndef IN_RING3
            return VINF_CPUM_R3_MSR_WRITE;
#else  /* IN_RING3 */
            /* First, update all but the TSC-page enable bit. */
            pHv->u64TscPageMsr = (uRawValue & ~MSR_GIM_HV_REF_TSC_ENABLE_BIT);

            /* Is the guest disabling the TSC-page? */
            bool fEnable = RT_BOOL(uRawValue & MSR_GIM_HV_REF_TSC_ENABLE_BIT);
            if (!fEnable)
            {
                gimR3HvDisableTscPage(pVM);
                pHv->u64TscPageMsr = uRawValue;
                return VINF_SUCCESS;
            }

            /* Enable the TSC-page. */
            RTGCPHYS GCPhysTscPage = MSR_GIM_HV_REF_TSC_GUEST_PFN(uRawValue) << PAGE_SHIFT;
            int rc = gimR3HvEnableTscPage(pVM, GCPhysTscPage, false /* fUseThisTscSequence */, 0 /* uTscSequence */);
            if (RT_SUCCESS(rc))
            {
                pHv->u64TscPageMsr = uRawValue;
                return VINF_SUCCESS;
            }

            return VERR_CPUM_RAISE_GP_0;
#endif /* IN_RING3 */
        }

        case MSR_GIM_HV_RESET:
        {
#ifndef IN_RING3
            return VINF_CPUM_R3_MSR_WRITE;
#else
            if (MSR_GIM_HV_RESET_IS_SET(uRawValue))
            {
                LogRel(("GIM: HyperV: Reset initiated through MSR\n"));
                int rc = PDMDevHlpVMReset(pVM->gim.s.pDevInsR3);
                AssertRC(rc);
            }
            /* else: Ignore writes to other bits. */
            return VINF_SUCCESS;
#endif /* IN_RING3 */
        }

        case MSR_GIM_HV_CRASH_CTL:
        {
#ifndef IN_RING3
            return VINF_CPUM_R3_MSR_WRITE;
#else
            if (uRawValue & MSR_GIM_HV_CRASH_CTL_NOTIFY_BIT)
            {
                LogRel(("GIM: HyperV: Guest indicates a fatal condition! P0=%#RX64 P1=%#RX64 P2=%#RX64 P3=%#RX64 P4=%#RX64\n",
                        pHv->uCrashP0, pHv->uCrashP1, pHv->uCrashP2, pHv->uCrashP3, pHv->uCrashP4));
            }
            return VINF_SUCCESS;
#endif
        }

        case MSR_GIM_HV_CRASH_P0:  pHv->uCrashP0 = uRawValue;  return VINF_SUCCESS;
        case MSR_GIM_HV_CRASH_P1:  pHv->uCrashP1 = uRawValue;  return VINF_SUCCESS;
        case MSR_GIM_HV_CRASH_P2:  pHv->uCrashP2 = uRawValue;  return VINF_SUCCESS;
        case MSR_GIM_HV_CRASH_P3:  pHv->uCrashP3 = uRawValue;  return VINF_SUCCESS;
        case MSR_GIM_HV_CRASH_P4:  pHv->uCrashP4 = uRawValue;  return VINF_SUCCESS;

        case MSR_GIM_HV_TIME_REF_COUNT:     /* Read-only MSRs. */
        case MSR_GIM_HV_VP_INDEX:
        case MSR_GIM_HV_TSC_FREQ:
        case MSR_GIM_HV_APIC_FREQ:
            LogFunc(("WrMsr on read-only MSR %#RX32 -> #GP(0)\n", idMsr));
            return VERR_CPUM_RAISE_GP_0;

        default:
        {
#ifdef IN_RING3
            static uint32_t s_cTimes = 0;
            if (s_cTimes++ < 20)
                LogRel(("GIM: HyperV: Unknown/invalid WrMsr (%#x,%#x`%08x) -> #GP(0)\n", idMsr,
                        uRawValue & UINT64_C(0xffffffff00000000), uRawValue & UINT64_C(0xffffffff)));
#endif
            LogFunc(("Unknown/invalid WrMsr (%#RX32,%#RX64) -> #GP(0)\n", idMsr, uRawValue));
            break;
        }
    }

    return VERR_CPUM_RAISE_GP_0;
}
RTR3DECL(bool) RTR3InitIsUnobtrusive(void)
{
    return RT_BOOL(g_fInitFlags & RTR3INIT_FLAGS_UNOBTRUSIVE);
}
Exemple #27
0
void UIFrameBufferQImage::resizeEvent(UIResizeEvent *pEvent)
{
#if 0
    LogFlowFunc (("fmt=%d, vram=%p, bpp=%d, bpl=%d, width=%d, height=%d\n",
                  pEvent->pixelFormat(), pEvent->VRAM(),
                  pEvent->bitsPerPixel(), pEvent->bytesPerLine(),
                  pEvent->width(), pEvent->height()));
#endif

    m_width = pEvent->width();
    m_height = pEvent->height();

    bool bRemind = false;
    bool bFallback = false;
    ulong bitsPerLine = pEvent->bytesPerLine() * 8;

    /* check if we support the pixel format and can use the guest VRAM directly */
    if (pEvent->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB)
    {
        QImage::Format format;
        switch (pEvent->bitsPerPixel())
        {
        /* 32-, 8- and 1-bpp are the only depths supported by QImage */
        case 32:
            format = QImage::Format_RGB32;
            break;
        case 8:
            format = QImage::Format_Indexed8;
            bRemind = true;
            break;
        case 1:
            format = QImage::Format_Mono;
            bRemind = true;
            break;
        default:
            format = QImage::Format_Invalid; /* set it to something so gcc keeps quiet. */
            bRemind = true;
            bFallback = true;
            break;
        }

        if (!bFallback)
        {
            /* QImage only supports 32-bit aligned scan lines... */
            Assert ((pEvent->bytesPerLine() & 3) == 0);
            bFallback = ((pEvent->bytesPerLine() & 3) != 0);
        }
        if (!bFallback)
        {
            /* ...and the scan lines ought to be a whole number of pixels. */
            Assert ((bitsPerLine & (pEvent->bitsPerPixel() - 1)) == 0);
            bFallback = ((bitsPerLine & (pEvent->bitsPerPixel() - 1)) != 0);
        }
        if (!bFallback)
        {
            Assert (bitsPerLine / pEvent->bitsPerPixel() >= m_width);
            bFallback = RT_BOOL (bitsPerLine / pEvent->bitsPerPixel() < m_width);
        }
        if (!bFallback)
        {
            m_img = QImage ((uchar *) pEvent->VRAM(), m_width, m_height, bitsPerLine / 8, format);
            m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
            m_bUsesGuestVRAM = true;
        }
    }
    else
    {
        bFallback = true;
    }

    if (bFallback)
    {
        /* we don't support either the pixel format or the color depth,
         * bFallback to a self-provided 32bpp RGB buffer */
        m_img = QImage (m_width, m_height, QImage::Format_RGB32);
        m_img.fill(0);
        m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
        m_bUsesGuestVRAM = false;
    }

    if (bRemind)
        msgCenter().remindAboutWrongColorDepth(pEvent->bitsPerPixel(), 32);
}
Exemple #28
0
RTDECL(int) RTPathSplit(const char *pszPath, PRTPATHSPLIT pSplit, size_t cbSplit, uint32_t fFlags)
{
    /*
     * Input validation.
     */
    AssertReturn(cbSplit >= RT_UOFFSETOF(RTPATHSPLIT, apszComps), VERR_INVALID_PARAMETER);
    AssertPtrReturn(pSplit, VERR_INVALID_POINTER);
    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
    AssertReturn(*pszPath, VERR_PATH_ZERO_LENGTH);
    AssertReturn(RTPATH_STR_F_IS_VALID(fFlags, 0), VERR_INVALID_FLAGS);

    /*
     * Use RTPathParse to do the parsing.
     * - This makes the ASSUMPTION that the output of this function is greater
     *   or equal to that of RTPathParsed.
     * - We're aliasing the buffer here, so use volatile to avoid issues due to
     *   compiler optimizations.
     */
    RTPATHPARSED volatile  *pParsedVolatile = (RTPATHPARSED volatile *)pSplit;
    RTPATHSPLIT  volatile  *pSplitVolatile  = (RTPATHSPLIT  volatile *)pSplit;

    AssertCompile(sizeof(*pParsedVolatile) <= sizeof(*pSplitVolatile));
    AssertCompile(sizeof(pParsedVolatile->aComps[0]) <= sizeof(pSplitVolatile->apszComps[0]));

    int rc = RTPathParse(pszPath, (PRTPATHPARSED)pParsedVolatile, cbSplit, fFlags);
    if (RT_FAILURE(rc) && rc != VERR_BUFFER_OVERFLOW)
        return rc;

    /*
     * Calculate the required buffer space.
     */
    uint16_t const  cComps    = pParsedVolatile->cComps;
    uint16_t const  fProps    = pParsedVolatile->fProps;
    uint16_t const  cchPath   = pParsedVolatile->cchPath;
    uint16_t const  offSuffix = pParsedVolatile->offSuffix;
    uint32_t        cbNeeded  = RT_OFFSETOF(RTPATHSPLIT, apszComps[cComps])
                              + cchPath
                              + RTPATH_PROP_FIRST_NEEDS_NO_SLASH(fProps) /* zero terminator for root spec. */
                              - RT_BOOL(fProps & RTPATH_PROP_DIR_SLASH) /* counted by cchPath, not included in the comp str. */
                              + 1; /* zero terminator. */
    if (cbNeeded > cbSplit)
    {
        pSplitVolatile->cbNeeded = cbNeeded;
        return VERR_BUFFER_OVERFLOW;
    }
    Assert(RT_SUCCESS(rc));

    /*
     * Convert the array and copy the strings, both backwards.
     */
    char    *psz     = (char *)pSplit + cbNeeded;
    uint32_t idxComp = cComps - 1;

    /* the final component first (because of suffix handling). */
    uint16_t offComp = pParsedVolatile->aComps[idxComp].off;
    uint16_t cchComp = pParsedVolatile->aComps[idxComp].cch;

    *--psz = '\0';
    psz -= cchComp;
    memcpy(psz, &pszPath[offComp], cchComp);
    pSplitVolatile->apszComps[idxComp] = psz;

    char *pszSuffix;
    if (offSuffix >= offComp + cchComp)
        pszSuffix = &psz[cchComp];
    else
        pszSuffix = &psz[offSuffix - offComp];

    /* the remainder */
    while (idxComp-- > 0)
    {
        offComp = pParsedVolatile->aComps[idxComp].off;
        cchComp = pParsedVolatile->aComps[idxComp].cch;
        *--psz = '\0';
        psz -= cchComp;
        memcpy(psz, &pszPath[offComp], cchComp);
        pSplitVolatile->apszComps[idxComp] = psz;
    }

    /*
     * Store / reshuffle the non-array bits. This MUST be done after finishing
     * the array processing because there may be members in RTPATHSPLIT
     * overlapping the array of RTPATHPARSED.
     */
    AssertCompileMembersSameSizeAndOffset(RTPATHPARSED, cComps,  RTPATHSPLIT, cComps);  Assert(pSplitVolatile->cComps == cComps);
    AssertCompileMembersSameSizeAndOffset(RTPATHPARSED, fProps,  RTPATHSPLIT, fProps);  Assert(pSplitVolatile->fProps == fProps);
    AssertCompileMembersSameSizeAndOffset(RTPATHPARSED, cchPath, RTPATHSPLIT, cchPath); Assert(pSplitVolatile->cchPath == cchPath);
    pSplitVolatile->u16Reserved = 0;
    pSplitVolatile->cbNeeded    = cbNeeded;
    pSplitVolatile->pszSuffix   = pszSuffix;

    return rc;
}
Exemple #29
0
void UIFrameBufferQImage::resizeEvent(UIResizeEvent *pEvent)
{
    /* Invalidate visible-region if necessary: */
    if (m_pMachineView->machineLogic()->visualStateType() == UIVisualStateType_Seamless &&
        (m_width != pEvent->width() || m_height != pEvent->height()))
    {
        lock();
        m_syncVisibleRegion = QRegion();
        m_asyncVisibleRegion = QRegion();
        unlock();
    }

    /* Remember new width/height: */
    m_width = pEvent->width();
    m_height = pEvent->height();

    /* Check if we support the pixel format and can use the guest VRAM directly: */
    bool bRemind = false;
    bool bFallback = false;
    ulong bitsPerLine = pEvent->bytesPerLine() * 8;
    if (pEvent->pixelFormat() == FramebufferPixelFormat_FOURCC_RGB)
    {
        QImage::Format format;
        switch (pEvent->bitsPerPixel())
        {
            /* 32-, 8- and 1-bpp are the only depths supported by QImage: */
            case 32:
                format = QImage::Format_RGB32;
                break;
            case 8:
                format = QImage::Format_Indexed8;
                bRemind = true;
                break;
            case 1:
                format = QImage::Format_Mono;
                bRemind = true;
                break;
            default:
                format = QImage::Format_Invalid;
                bRemind = true;
                bFallback = true;
                break;
        }

        if (!bFallback)
        {
            /* QImage only supports 32-bit aligned scan lines... */
            Assert((pEvent->bytesPerLine() & 3) == 0);
            bFallback = ((pEvent->bytesPerLine() & 3) != 0);
        }
        if (!bFallback)
        {
            /* ...and the scan lines ought to be a whole number of pixels. */
            Assert((bitsPerLine & (pEvent->bitsPerPixel() - 1)) == 0);
            bFallback = ((bitsPerLine & (pEvent->bitsPerPixel() - 1)) != 0);
        }
        if (!bFallback)
        {
            /* Make sure constraints are also passed: */
            Assert(bitsPerLine / pEvent->bitsPerPixel() >= m_width);
            bFallback = RT_BOOL(bitsPerLine / pEvent->bitsPerPixel() < m_width);
        }
        if (!bFallback)
        {
            /* Finally compose image using VRAM directly: */
            m_img = QImage((uchar *)pEvent->VRAM(), m_width, m_height, bitsPerLine / 8, format);
            m_uPixelFormat = FramebufferPixelFormat_FOURCC_RGB;
            m_bUsesGuestVRAM = true;
        }
    }
    else
        bFallback = true;

    /* Fallback if requested: */
    if (bFallback)
    {
        LogRelFlow(("UIFrameBufferQImage::resizeEvent: "
                    "Going fallback due to frame-buffer format become invalid: "
                    "Format=%lu, BitsPerPixel=%lu, BytesPerLine=%lu, Size=%lux%lu\n",
                    (unsigned long)pEvent->pixelFormat(),
                    (unsigned long)pEvent->bitsPerPixel(),
                    (unsigned long)pEvent->bytesPerLine(),
                    (unsigned long)pEvent->width(),
                    (unsigned long)pEvent->height()));
        goFallback();
    }

    /* Remind if requested: */
    if (bRemind)
        popupCenter().remindAboutWrongColorDepth(m_pMachineView->machineWindow(),
                                                      pEvent->bitsPerPixel(), 32);
    else
        popupCenter().forgetAboutWrongColorDepth(m_pMachineView->machineWindow());
}
Exemple #30
0
/** Does the guest currently rely on the host to draw the mouse cursor or
 * can it switch to doing it itself in software? */
bool Mouse::guestNeedsHostCursor(void)
{
    return RT_BOOL(mfVMMDevGuestCaps & VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
}