예제 #1
0
int GuestCtrlCallback::Init(eVBoxGuestCtrlCallbackType enmType)
{
    LogFlowFuncEnter();

    AssertReturn(enmType > VBOXGUESTCTRLCALLBACKTYPE_UNKNOWN, VERR_INVALID_PARAMETER);
    Assert((pvData == NULL) && !cbData);

    switch (enmType)
    {
        case VBOXGUESTCTRLCALLBACKTYPE_EXEC_START:
        {
            pvData = (PCALLBACKDATAEXECSTATUS)RTMemAlloc(sizeof(CALLBACKDATAEXECSTATUS));
            AssertPtrReturn(pvData, VERR_NO_MEMORY);
            RT_BZERO(pvData, sizeof(CALLBACKDATAEXECSTATUS));
            cbData = sizeof(CALLBACKDATAEXECSTATUS);
            break;
        }

        case VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT:
        {
            pvData = (PCALLBACKDATAEXECOUT)RTMemAlloc(sizeof(CALLBACKDATAEXECOUT));
            AssertPtrReturn(pvData, VERR_NO_MEMORY);
            RT_BZERO(pvData, sizeof(CALLBACKDATAEXECOUT));
            cbData = sizeof(CALLBACKDATAEXECOUT);
            break;
        }

        case VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS:
        {
            PCALLBACKDATAEXECINSTATUS pData = (PCALLBACKDATAEXECINSTATUS)RTMemAlloc(sizeof(CALLBACKDATAEXECINSTATUS));
            AssertPtrReturn(pData, VERR_NO_MEMORY);
            RT_BZERO(pData, sizeof(CALLBACKDATAEXECINSTATUS));
            cbData = sizeof(CALLBACKDATAEXECINSTATUS);
            break;
        }

        default:
            AssertMsgFailed(("Unknown callback type specified (%d)\n", enmType));
            break;
    }

    int rc = GuestCtrlEvent::Init();
    if (RT_SUCCESS(rc))
        mType  = enmType;

    LogFlowFuncLeaveRC(rc);
    return rc;
}
예제 #2
0
/**
 * Allocates memory from the specified heap.
 *
 * @returns Address of the allocated memory.
 * @param   cb                  The number of bytes to allocate.
 * @param   pszTag              The tag.
 * @param   fZero               Whether to zero the memory or not.
 * @param   fProtExec           PROT_EXEC or 0.
 */
static void *rtMemPagePosixAlloc(size_t cb, const char *pszTag, bool fZero, int fProtExec)
{
    /*
     * Validate & adjust the input.
     */
    Assert(cb > 0);
    NOREF(pszTag);
    cb = RT_ALIGN_Z(cb, PAGE_SIZE);

    /*
     * Do the allocation.
     */
    void *pv = mmap(NULL, cb,
                    PROT_READ | PROT_WRITE | fProtExec,
                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (pv != MAP_FAILED)
    {
        AssertPtr(pv);
        if (fZero)
            RT_BZERO(pv, cb);
    }
    else
        pv = NULL;

    return pv;
}
예제 #3
0
int DumpHtml(char* src, size_t cb)
{
    size_t lenght = 0;
    int rc = RTStrNLenEx(src, cb, &lenght);
    if (RT_SUCCESS(rc))
    {
        char* buf = (char*)RTMemAlloc(cb + 1);
        if (buf != NULL)
        {
            RT_BZERO(buf, cb + 1);
            rc = RTStrCopy(buf, cb, (const char*)src);
            if (RT_SUCCESS(rc))
            {
                for (int i = 0; i < cb; ++i)
                {
                    if (buf[i] == '\n' || buf[i] == '\r')
                        buf[i] = ' ';
                }
            }
            else
            {
                Log(("Error in copying string.\n"));
            }
            Log(("Removed \\r\\n: %s\n", buf));
            RTMemFree(buf);
        }
        else
        {
            rc = VERR_NO_MEMORY;
            Log(("Not enough memory to allocate buffer.\n"));
        }
    }
    return rc;
}
예제 #4
0
파일: tar.cpp 프로젝트: mcenirm/vbox
static int rtTarAppendZeros(PRTTARFILEINTERNAL pFileInt, uint64_t cbSize)
{
    /* Allocate a temporary buffer for copying the tar content in blocks. */
    size_t cbTmp = 0;
    void *pvTmp = rtTarMemTmpAlloc(&cbTmp);
    if (!pvTmp)
        return VERR_NO_MEMORY;
    RT_BZERO(pvTmp, cbTmp);

    int rc = VINF_SUCCESS;
    uint64_t cbAllWritten = 0;
    size_t cbWritten = 0;
    for (;;)
    {
        if (cbAllWritten >= cbSize)
            break;
        size_t cbToWrite = RT_MIN(cbSize - cbAllWritten, cbTmp);
        rc = RTTarFileWriteAt(pFileInt, pFileInt->offCurrent, pvTmp, cbToWrite, &cbWritten);
        if (RT_FAILURE(rc))
            break;
        cbAllWritten += cbWritten;
    }

    RTMemTmpFree(pvTmp);

    return rc;
}
RTDECL(int) RTSystemShutdown(RTMSINTERVAL cMsDelay, uint32_t fFlags, const char *pszLogMsg)
{
    AssertPtrReturn(pszLogMsg, VERR_INVALID_POINTER);
    AssertReturn(!(fFlags & ~RTSYSTEM_SHUTDOWN_VALID_MASK), VERR_INVALID_PARAMETER);

    /*
     * Assemble the argument vector.
     */
    int         iArg = 0;
    const char *apszArgs[6];

    RT_BZERO(apszArgs, sizeof(apszArgs));

    apszArgs[iArg++] = "/sbin/shutdown";
    switch (fFlags & RTSYSTEM_SHUTDOWN_ACTION_MASK)
    {
        case RTSYSTEM_SHUTDOWN_HALT:
            apszArgs[iArg++] = "-h";
            apszArgs[iArg++] = "-H";
            break;
        case RTSYSTEM_SHUTDOWN_REBOOT:
            apszArgs[iArg++] = "-r";
            break;
        case RTSYSTEM_SHUTDOWN_POWER_OFF:
        case RTSYSTEM_SHUTDOWN_POWER_OFF_HALT:
            apszArgs[iArg++] = "-h";
            apszArgs[iArg++] = "-P";
            break;
    }

    char szWhen[80];
    if (cMsDelay < 500)
        strcpy(szWhen, "now");
    else
        RTStrPrintf(szWhen, sizeof(szWhen), "%u", (unsigned)((cMsDelay + 499) / 1000));
    apszArgs[iArg++] = szWhen;

    apszArgs[iArg++] = pszLogMsg;


    /*
     * Start the shutdown process and wait for it to complete.
     */
    RTPROCESS hProc;
    int rc = RTProcCreate(apszArgs[0], apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, &hProc);
    if (RT_FAILURE(rc))
        return rc;

    RTPROCSTATUS ProcStatus;
    rc = RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus);
    if (RT_SUCCESS(rc))
    {
        if (   ProcStatus.enmReason != RTPROCEXITREASON_NORMAL
            || ProcStatus.iStatus   != 0)
            rc = VERR_SYS_SHUTDOWN_FAILED;
    }

    return rc;
}
예제 #6
0
static void testCopy1(RTTEST hTest)
{
    RTTestISub("RTStrCopy");

    char *pszBuf4H = (char *)RTTestGuardedAllocHead(hTest, 4);
    char *pszBuf4T = (char *)RTTestGuardedAllocTail(hTest, 4);
    RTTESTI_CHECK_RC(RTStrCopy(pszBuf4H, 4, "abc"), VINF_SUCCESS);
    RTTESTI_CHECK(strcmp(pszBuf4H, "abc") == 0);
    RTTESTI_CHECK_RC(RTStrCopy(pszBuf4T, 4, "abc"), VINF_SUCCESS);
    RTTESTI_CHECK(strcmp(pszBuf4T, "abc") == 0);

    RT_BZERO(pszBuf4H, 4); RT_BZERO(pszBuf4T, 4);
    RTTESTI_CHECK_RC(RTStrCopy(pszBuf4H, 4, "abcd"), VERR_BUFFER_OVERFLOW);
    RTTESTI_CHECK(strcmp(pszBuf4H, "abc") == 0);
    RTTESTI_CHECK_RC(RTStrCopy(pszBuf4T, 4, "abcd"), VERR_BUFFER_OVERFLOW);
    RTTESTI_CHECK(strcmp(pszBuf4T, "abc") == 0);
}
HRESULT VBoxCredProvCredential::kerberosLogonSerialize(const KERB_INTERACTIVE_LOGON *pLogonIn,
                                                       PBYTE *ppPackage, DWORD *pcbPackage)
{
    AssertPtrReturn(pLogonIn,   E_INVALIDARG);
    AssertPtrReturn(ppPackage,  E_INVALIDARG);
    AssertPtrReturn(pcbPackage, E_INVALIDARG);

    /*
     * First, allocate enough space for the logon structure itself and separate
     * string buffers right after it to store the actual user, password and domain
     * credentials.
     */
    DWORD cbLogon = sizeof(KERB_INTERACTIVE_UNLOCK_LOGON)
                  + pLogonIn->LogonDomainName.Length +
                  + pLogonIn->UserName.Length +
                  + pLogonIn->Password.Length;

#ifdef DEBUG
    VBoxCredProvVerbose(3, "VBoxCredProvCredential::AllocateLogonPackage: Allocating %ld bytes (%d bytes credentials)\n",
                        cbLogon, cbLogon - sizeof(KERB_INTERACTIVE_UNLOCK_LOGON));
#endif

    KERB_INTERACTIVE_UNLOCK_LOGON *pLogon = (KERB_INTERACTIVE_UNLOCK_LOGON*)CoTaskMemAlloc(cbLogon);
    if (!pLogon)
        return E_OUTOFMEMORY;

    /* Let our byte buffer point to the end of our allocated structure so that it can
     * be used to store the credential data sequentially in a binary blob
     * (without terminating \0). */
    PBYTE pbBuffer = (PBYTE)pLogon + sizeof(KERB_INTERACTIVE_UNLOCK_LOGON);

    /* The buffer of the packed destination string does not contain the actual
     * string content but a relative offset starting at the given
     * KERB_INTERACTIVE_UNLOCK_LOGON structure. */
#define KERB_CRED_INIT_PACKED(StringDst, StringSrc, LogonOffset)         \
    StringDst.Length         = StringSrc.Length;                         \
    StringDst.MaximumLength  = StringSrc.Length;                         \
    StringDst.Buffer         = (PWSTR)pbBuffer;                          \
    memcpy(StringDst.Buffer, StringSrc.Buffer, StringDst.Length);        \
    StringDst.Buffer         = (PWSTR)(pbBuffer - (PBYTE)LogonOffset);   \
    pbBuffer                += StringDst.Length;

    RT_BZERO(&pLogon->LogonId, sizeof(LUID));

    KERB_INTERACTIVE_LOGON *pLogonOut = &pLogon->Logon;
    pLogonOut->MessageType = pLogonIn->MessageType;

    KERB_CRED_INIT_PACKED(pLogonOut->LogonDomainName, pLogonIn->LogonDomainName, pLogon);
    KERB_CRED_INIT_PACKED(pLogonOut->UserName       , pLogonIn->UserName,        pLogon);
    KERB_CRED_INIT_PACKED(pLogonOut->Password       , pLogonIn->Password,        pLogon);

    *ppPackage  = (PBYTE)pLogon;
    *pcbPackage = cbLogon;

#undef KERB_CRED_INIT_PACKED

    return S_OK;
}
VBoxCredProvCredential::VBoxCredProvCredential(void) :
    m_enmUsageScenario(CPUS_INVALID),
    m_cRefs(1),
    m_pEvents(NULL),
    m_fHaveCreds(false)
{
    VBoxCredProvVerbose(0, "VBoxCredProvCredential: Created\n");
    VBoxCredentialProviderAcquire();
    RT_BZERO(m_apwszCredentials, sizeof(PRTUTF16) * VBOXCREDPROV_NUM_FIELDS);
}
예제 #9
0
/* 
* Converts clipboard data from CF_HTML format to mimie clipboard format
* Returns allocated buffer that contains html converted to text/html mime type
* return result code
* parameters - output buffer and size of output buffer
* It allocates the buffer needed for storing converted fragment 
* Allocated buffer should be destroyed by RTMemFree after usage
*/
int ConvertCFHtmlToMime(const char *pcszSource, const uint32_t cch, char **ppszOutput, size_t *pcCh)
{
    char* result = NULL;

    Assert(pcszSource);
    Assert(cch);
    Assert(ppszOutput);
    Assert(pcCh);

    size_t cStartOffset, cEndOffset;
    int rc = GetHeaderValue(pcszSource, "StartFragment:", &cStartOffset);
    if (!RT_SUCCESS(rc))
    {
        LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected StartFragment. rc = %Rrc.\n", rc));
        return VERR_INVALID_PARAMETER;
    }
    rc = GetHeaderValue(pcszSource, "EndFragment:", &cEndOffset);
    if (!RT_SUCCESS(rc))
    {
        LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment. rc = %Rrc.\n", rc));
        return VERR_INVALID_PARAMETER;
    }
    if (cStartOffset > 0 && cEndOffset > 0 && cEndOffset > cStartOffset)
    {
        size_t cSubstrlen = cEndOffset - cStartOffset;
        result = (char*)RTMemAlloc(cSubstrlen + 1);
        if (result)
        {
            RT_BZERO(result, cSubstrlen + 1);
            rc = RTStrCopyEx(result, cSubstrlen + 1, pcszSource + cStartOffset, cSubstrlen);
            if (RT_SUCCESS(rc))
            {
                *ppszOutput = result;
                *pcCh = cSubstrlen + 1;
            }
            else
            {
                LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment. rc = %Rrc\n", rc));
                return rc;
            }
        }
        else
        {
            LogRelFlowFunc(("Error: Unknown CF_HTML format. Expected EndFragment.\n"));
            return VERR_NO_MEMORY;
        }
    }

return VINF_SUCCESS;
}
RTDECL(int) RTCrDigestReset(RTCRDIGEST hDigest)
{
    PRTCRDIGESTINT pThis = hDigest;
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertReturn(pThis->u32Magic == RTCRDIGESTINT_MAGIC, VERR_INVALID_HANDLE);

    pThis->cbConsumed = 0;
    pThis->uState = RTCRDIGEST_STATE_READY;

    int rc = VINF_SUCCESS;
    if (pThis->pDesc->pfnInit)
    {
        rc = pThis->pDesc->pfnInit(pThis->pvState, NULL, true /*fReInit*/);
        if (RT_FAILURE(rc))
            pThis->uState = RTCRDIGEST_STATE_BUSTED;
        RT_BZERO(&pThis->abState[pThis->offHash], pThis->pDesc->cbHash);
    }
    else
    {
        Assert(!pThis->pDesc->pfnNew);
        RT_BZERO(pThis->pvState, pThis->offHash + pThis->pDesc->cbHash);
    }
    return rc;
}
예제 #11
0
DECLCALLBACK(void) VBoxClipboardDestroy(void *pInstance)
{
    AssertPtrReturnVoid(pInstance);

    PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)pInstance;
    AssertPtr(pCtx);

    /* Make sure that we are disconnected. */
    Assert(pCtx->u32ClientID == 0);

    vboxClipboardDestroy(pCtx);
    RT_BZERO(pCtx, sizeof(VBOXCLIPBOARDCONTEXT));

    return;
}
예제 #12
0
RTDECL(int) RTAsn1MemGrowArray(PRTASN1ALLOCATION pAllocation, void **ppvArray, size_t cbEntry,
                               uint32_t cCurrent, uint32_t cNew)
{
    AssertReturn(pAllocation->pAllocator != NULL, VERR_WRONG_ORDER);
    AssertReturn(cbEntry > 0, VERR_INVALID_PARAMETER);
    AssertReturn(cNew > cCurrent, VERR_INVALID_PARAMETER);
    AssertReturn(cNew < _1M, VERR_OUT_OF_RANGE);

    pAllocation->cReallocs++;

    void *pvOld = *ppvArray;

    /* Initial allocation? */
    if (cCurrent == 0)
    {
        AssertReturn(pvOld == NULL, VERR_INVALID_PARAMETER);
        AssertReturn(cNew != 0, VERR_INVALID_PARAMETER);
        return pAllocation->pAllocator->pfnAlloc(pAllocation->pAllocator, pAllocation, ppvArray, cNew * cbEntry);
    }

    /* Do we need to grow the allocation or did we already allocate sufficient memory in a previous call? */
    size_t cbNew = cNew * cbEntry;
    if (pAllocation->cbAllocated < cbNew)
    {
        /* Need to grow.  Adjust the new size according to how many times we've been called. */
        if (pAllocation->cReallocs > 2)
        {
            if (pAllocation->cReallocs > 8)
                cNew += 8;
            else if (pAllocation->cReallocs < 4)
                cNew += 2;
            else
                cNew += 4;
            cbNew += cNew * cbEntry;
        }

        int rc = pAllocation->pAllocator->pfnRealloc(pAllocation->pAllocator, pAllocation, pvOld, ppvArray, cbNew);
        if (RT_FAILURE(rc))
            return rc;
        Assert(pAllocation->cbAllocated >= cbNew);

        /* Clear the memory. */
        size_t cbOld = cCurrent * cbEntry;
        RT_BZERO((uint8_t *)*ppvArray + cbOld, pAllocation->cbAllocated - cbOld);
    }

    return VINF_SUCCESS;
}
예제 #13
0
void vboxClipboardDump(const void *pv, size_t cb, uint32_t u32Format)
{
    if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    {
        Log(("DUMP: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT:\n"));
        if (pv && cb)
        {
            Log(("%ls\n", pv));
        }
        else
        {
            Log(("%p %d\n", pv, cb));
        }
    }
    else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    {
        dprintf(("DUMP: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
    }
    else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_HTML)
    {
        Log(("DUMP: VBOX_SHARED_CLIPBOARD_FMT_HTML:\n"));
        if (pv && cb)
        {
            Log(("%s\n", pv));
            
            //size_t cb = RTStrNLen(pv, );
            char* buf = (char*)RTMemAlloc(cb + 1);
            RT_BZERO(buf, cb);
            RTStrCopy(buf, cb, (const char*)pv);
            for (int i = 0; i < cb; ++i)
            {
                if (buf[i] == '\n' || buf[i] == '\r')
                    buf[i] = ' ';
            }
            
            Log(("%s\n", buf));
            RTMemFree(buf);
        }
        else
        {
            Log(("%p %d\n", pv, cb));
        }
    }
    else
    {
        dprintf(("DUMP: invalid format %02X\n", u32Format));
    }
}
예제 #14
0
/**
 * Avoids some gotos in rtHeapPageAllocFromBlock.
 *
 * @returns VINF_SUCCESS.
 * @param   pBlock          The block.
 * @param   iPage           The page to start allocating at.
 * @param   cPages          The number of pages.
 * @param   fZero           Whether to clear them.
 * @param   ppv             Where to return the allocation address.
 */
DECLINLINE(int) rtHeapPageAllocFromBlockSuccess(PRTHEAPPAGEBLOCK pBlock, uint32_t iPage,  size_t cPages, bool fZero, void **ppv)
{
    PRTHEAPPAGE pHeap = pBlock->pHeap;

    ASMBitSet(&pBlock->bmFirst[0], iPage);
    pBlock->cFreePages -= cPages;
    pHeap->cFreePages  -= cPages;
    if (!pHeap->pHint2 || pHeap->pHint2->cFreePages < pBlock->cFreePages)
        pHeap->pHint2 = pBlock;
    pHeap->cAllocCalls++;

    void *pv = (uint8_t *)pBlock->Core.Key + (iPage << PAGE_SHIFT);
    *ppv = pv;
    if (fZero)
        RT_BZERO(pv, cPages << PAGE_SHIFT);

    return VINF_SUCCESS;
}
DECLCALLBACK(int) VBoxClipboardInit(const PVBOXSERVICEENV pEnv, void **ppInstance)
{
    LogFlowFuncEnter();

    PVBOXCLIPBOARDCONTEXT pCtx = &g_Ctx; /* Only one instance for now. */
    AssertPtr(pCtx);

    if (pCtx->pEnv)
    {
        /* Clipboard was already initialized. 2 or more instances are not supported. */
        return VERR_NOT_SUPPORTED;
    }

    if (VbglR3AutoLogonIsRemoteSession())
    {
        /* Do not use clipboard for remote sessions. */
        LogRel(("Clipboard: Clipboard has been disabled for a remote session\n"));
        return VERR_NOT_SUPPORTED;
    }

    RT_BZERO(pCtx, sizeof(VBOXCLIPBOARDCONTEXT));

    pCtx->pEnv = pEnv;

    /* Check that new Clipboard API is available */
    VBoxClipboardWinCheckAndInitNewAPI(&pCtx->Win.newAPI);

    int rc = VbglR3ClipboardConnect(&pCtx->u32ClientID);
    if (RT_SUCCESS(rc))
    {
        rc = vboxClipboardCreateWindow(pCtx);
        if (RT_SUCCESS(rc))
        {
            *ppInstance = pCtx;
        }
        else
        {
            VbglR3ClipboardDisconnect(pCtx->u32ClientID);
        }
    }

    LogFlowFuncLeaveRC(rc);
    return rc;
}
static SHFLROOT initWithWritableMapping(RTTEST hTest,
                                        VBOXHGCMSVCFNTABLE *psvcTable,
                                        VBOXHGCMSVCHELPERS *psvcHelpers,
                                        const char *pcszFolderName,
                                        const char *pcszMapping)
{
    VBOXHGCMSVCPARM aParms[RT_MAX(SHFL_CPARMS_ADD_MAPPING,
                                  SHFL_CPARMS_MAP_FOLDER)];
    struct TESTSHFLSTRING FolderName;
    struct TESTSHFLSTRING Mapping;
    VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
    int rc;

    initTable(psvcTable, psvcHelpers);
    AssertReleaseRC(VBoxHGCMSvcLoad(psvcTable));
    AssertRelease(  psvcTable->pvService
                  = RTTestGuardedAllocTail(hTest, psvcTable->cbClient));
    RT_BZERO(psvcTable->pvService, psvcTable->cbClient);
    fillTestShflString(&FolderName, pcszFolderName);
    fillTestShflString(&Mapping, pcszMapping);
    aParms[0].setPointer(&FolderName,   RT_UOFFSETOF(SHFLSTRING, String)
                                      + FolderName.string.u16Size);
    aParms[1].setPointer(&Mapping,   RT_UOFFSETOF(SHFLSTRING, String)
                                   + Mapping.string.u16Size);
    aParms[2].setUInt32(1);
    rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_ADD_MAPPING,
                                SHFL_CPARMS_ADD_MAPPING, aParms);
    AssertReleaseRC(rc);
    aParms[0].setPointer(&Mapping,   RT_UOFFSETOF(SHFLSTRING, String)
                                   + Mapping.string.u16Size);
    aParms[1].setUInt32(0);  /* root */
    aParms[2].setUInt32('/');  /* delimiter */
    aParms[3].setUInt32(1);  /* case sensitive */
    psvcTable->pfnCall(psvcTable->pvService, &callHandle, 0,
                       psvcTable->pvService, SHFL_FN_MAP_FOLDER,
                       SHFL_CPARMS_MAP_FOLDER, aParms);
    AssertReleaseRC(callHandle.rc);
    return aParms[1].u.uint32;
}
/**
 * Applies flags to an allocation.
 *
 * @param   pv              The allocation.
 * @param   cb              The size of the allocation (page aligned).
 * @param   fFlags          RTMEMPAGEALLOC_F_XXX.
 */
DECLINLINE(void) rtMemPagePosixApplyFlags(void *pv, size_t cb, uint32_t fFlags)
{
#ifndef RT_OS_OS2
    if (fFlags & RTMEMPAGEALLOC_F_ADVISE_LOCKED)
    {
        int rc = mlock(pv, cb);
        AssertMsg(rc == 0, ("mlock %p LB %#zx -> %d errno=%d\n", pv, cb, rc, errno));
        NOREF(rc);
    }

# ifdef MADV_DONTDUMP
    if (fFlags & RTMEMPAGEALLOC_F_ADVISE_NO_DUMP)
    {
        int rc = madvise(pv, cb, MADV_DONTDUMP);
        AssertMsg(rc == 0, ("madvice %p LB %#zx MADV_DONTDUMP -> %d errno=%d\n", pv, cb, rc, errno));
        NOREF(rc);
    }
# endif
#endif

    if (fFlags & RTMEMPAGEALLOC_F_ZERO)
        RT_BZERO(pv, cb);
}
예제 #18
0
/**
 * Retrieves a descriptor of a specified field.
 *
 * @return  HRESULT
 * @param   dwIndex                 ID of field to retrieve descriptor for.
 * @param   ppFieldDescriptor       Pointer which receives the allocated field
 *                                  descriptor.
 */
HRESULT
VBoxCredProvProvider::GetFieldDescriptorAt(DWORD dwIndex, CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **ppFieldDescriptor)
{
    HRESULT hr = S_OK;
    if (   dwIndex < VBOXCREDPROV_NUM_FIELDS
        && ppFieldDescriptor)
    {
        PCREDENTIAL_PROVIDER_FIELD_DESCRIPTOR pcpFieldDesc =
            (PCREDENTIAL_PROVIDER_FIELD_DESCRIPTOR)CoTaskMemAlloc(sizeof(CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR));

        if (pcpFieldDesc)
        {
            const VBOXCREDPROV_FIELD &field = s_VBoxCredProvFields[dwIndex];

            RT_BZERO(pcpFieldDesc, sizeof(CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR));

            pcpFieldDesc->dwFieldID = field.desc.dwFieldID;
            pcpFieldDesc->cpft      = field.desc.cpft;
            if (field.desc.pszLabel)
                hr = SHStrDupW(field.desc.pszLabel, &pcpFieldDesc->pszLabel);
        }
        else
            hr = E_OUTOFMEMORY;

        if (SUCCEEDED(hr))
            *ppFieldDescriptor = pcpFieldDesc;
        else
            CoTaskMemFree(pcpFieldDesc);
    }
    else
        hr = E_INVALIDARG;

    VBoxCredProvVerbose(0, "VBoxCredProv::GetFieldDescriptorAt: dwIndex=%ld, ppDesc=0x%p, hr=0x%08x\n",
                        dwIndex, ppFieldDescriptor, hr);
    return hr;
}
예제 #19
0
/**
 * Retrieves a descriptor of a specified field.
 *
 * @return  HRESULT
 * @param   dwIndex                 ID of field to retrieve descriptor for.
 * @param   ppFieldDescriptor       Pointer which receives the allocated field
 *                                  descriptor.
 */
HRESULT
VBoxCredProvProvider::GetFieldDescriptorAt(DWORD dwIndex, CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **ppFieldDescriptor)
{
    HRESULT hr = S_OK;
    if (   dwIndex < VBOXCREDPROV_NUM_FIELDS
        && ppFieldDescriptor)
    {
        PCREDENTIAL_PROVIDER_FIELD_DESCRIPTOR pcpFieldDesc =
            (PCREDENTIAL_PROVIDER_FIELD_DESCRIPTOR)CoTaskMemAlloc(sizeof(CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR));

        if (pcpFieldDesc)
        {
            const VBOXCREDPROV_FIELD &field = s_VBoxCredProvDefaultFields[dwIndex];

            RT_BZERO(pcpFieldDesc, sizeof(CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR));

            pcpFieldDesc->dwFieldID     = field.desc.dwFieldID;
            pcpFieldDesc->cpft          = field.desc.cpft;

            PCRTUTF16 pcwszField = NULL;

            if (dwIndex != VBOXCREDPROV_FIELDID_PASSWORD) /* Don't ever get any password. Never ever, ever. */
            {
                if (m_pCred) /* If we have retrieved credentials, get the actual (current) value. */
                    pcwszField = m_pCred->getField(dwIndex);
                else /* Otherwise get the default value. */
                    pcwszField = field.desc.pszLabel;
            }

            hr = SHStrDupW(pcwszField ? pcwszField : L"", &pcpFieldDesc->pszLabel);

            VBoxCredProvVerbose(0, "VBoxCredProv::GetFieldDescriptorAt: dwIndex=%ld, pszLabel=%ls, hr=0x%08x\n",
                                dwIndex,
#ifdef DEBUG /* Don't show any (sensitive data) in release mode. */
                                pcwszField ? pcwszField : L"",
#else
                                L"XXX",
#endif
                                hr);

            pcpFieldDesc->guidFieldType = field.desc.guidFieldType;
        }
        else
            hr = E_OUTOFMEMORY;

        if (SUCCEEDED(hr))
        {
            *ppFieldDescriptor = pcpFieldDesc;
        }
        else if (pcpFieldDesc)
        {
            if (pcpFieldDesc->pszLabel)
            {
                CoTaskMemFree(pcpFieldDesc->pszLabel);
                pcpFieldDesc->pszLabel = NULL;
            }

            CoTaskMemFree(pcpFieldDesc);
        }
    }
    else
        hr = E_INVALIDARG;

    VBoxCredProvVerbose(0, "VBoxCredProv::GetFieldDescriptorAt: dwIndex=%ld, ppDesc=0x%p, hr=0x%08x\n",
                        dwIndex, ppFieldDescriptor, hr);
    return hr;
}
예제 #20
0
파일: uri.cpp 프로젝트: miguelinux/vbox
RTDECL(char *) RTUriCreate(const char *pszScheme, const char *pszAuthority, const char *pszPath, const char *pszQuery,
                           const char *pszFragment)
{
    if (!pszScheme) /* Scheme is minimum requirement */
        return NULL;

    char *pszResult = 0;
    char *pszAuthority1 = 0;
    char *pszPath1 = 0;
    char *pszQuery1 = 0;
    char *pszFragment1 = 0;

    do
    {
        /* Create the percent encoded strings and calculate the necessary uri
         * length. */
        size_t cbSize = strlen(pszScheme) + 1 + 1; /* plus zero byte */
        if (pszAuthority)
        {
            pszAuthority1 = rtUriPercentEncodeN(pszAuthority, RTSTR_MAX);
            if (!pszAuthority1)
                break;
            cbSize += strlen(pszAuthority1) + 2;
        }
        if (pszPath)
        {
            pszPath1 = rtUriPercentEncodeN(pszPath, RTSTR_MAX);
            if (!pszPath1)
                break;
            cbSize += strlen(pszPath1);
        }
        if (pszQuery)
        {
            pszQuery1 = rtUriPercentEncodeN(pszQuery, RTSTR_MAX);
            if (!pszQuery1)
                break;
            cbSize += strlen(pszQuery1) + 1;
        }
        if (pszFragment)
        {
            pszFragment1 = rtUriPercentEncodeN(pszFragment, RTSTR_MAX);
            if (!pszFragment1)
                break;
            cbSize += strlen(pszFragment1) + 1;
        }

        char *pszTmp = pszResult = (char *)RTStrAlloc(cbSize);
        if (!pszResult)
            break;
        RT_BZERO(pszTmp, cbSize);

        /* Compose the target uri string. */
        RTStrCatP(&pszTmp, &cbSize, pszScheme);
        RTStrCatP(&pszTmp, &cbSize, ":");
        if (pszAuthority1)
        {
            RTStrCatP(&pszTmp, &cbSize, "//");
            RTStrCatP(&pszTmp, &cbSize, pszAuthority1);
        }
        if (pszPath1)
        {
            RTStrCatP(&pszTmp, &cbSize, pszPath1);
        }
        if (pszQuery1)
        {
            RTStrCatP(&pszTmp, &cbSize, "?");
            RTStrCatP(&pszTmp, &cbSize, pszQuery1);
        }
        if (pszFragment1)
        {
            RTStrCatP(&pszTmp, &cbSize, "#");
            RTStrCatP(&pszTmp, &cbSize, pszFragment1);
        }
    } while (0);

    /* Cleanup */
    if (pszAuthority1)
        RTStrFree(pszAuthority1);
    if (pszPath1)
        RTStrFree(pszPath1);
    if (pszQuery1)
        RTStrFree(pszQuery1);
    if (pszFragment1)
        RTStrFree(pszFragment1);

    return pszResult;
}
예제 #21
0
/**
 * Deal with the 'slow' I/O control requests.
 *
 * @returns 0 on success, appropriate errno on failure.
 * @param   pSession    The session.
 * @param   ulCmd       The command.
 * @param   pvData      The request data.
 * @param   pTd         The calling thread.
 */
static int vgdrvFreeBSDIOCtlSlow(PVBOXGUESTSESSION pSession, u_long ulCmd, caddr_t pvData, struct thread *pTd)
{
    PVBGLREQHDR pHdr;
    uint32_t    cbReq = IOCPARM_LEN(ulCmd);
    void       *pvUser = NULL;

    /*
     * Buffered request?
     */
    if ((IOC_DIRMASK & ulCmd) == IOC_INOUT)
    {
        pHdr = (PVBGLREQHDR)pvData;
        if (RT_UNLIKELY(cbReq < sizeof(*pHdr)))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: cbReq=%#x < %#x; ulCmd=%#lx\n", cbReq, (int)sizeof(*pHdr), ulCmd));
            return EINVAL;
        }
        if (RT_UNLIKELY(pHdr->uVersion != VBGLREQHDR_VERSION))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: bad uVersion=%#x; ulCmd=%#lx\n", pHdr->uVersion, ulCmd));
            return EINVAL;
        }
        if (RT_UNLIKELY(   RT_MAX(pHdr->cbIn, pHdr->cbOut) != cbReq
                        || pHdr->cbIn < sizeof(*pHdr)
                        || (pHdr->cbOut < sizeof(*pHdr) && pHdr->cbOut != 0)))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: max(%#x,%#x) != %#x; ulCmd=%#lx\n", pHdr->cbIn, pHdr->cbOut, cbReq, ulCmd));
            return EINVAL;
        }
    }
    /*
     * Big unbuffered request?
     */
    else if ((IOC_DIRMASK & ulCmd) == IOC_VOID && !cbReq)
    {
        /*
         * Read the header, validate it and figure out how much that needs to be buffered.
         */
        VBGLREQHDR Hdr;
        pvUser = *(void **)pvData;
        int rc = copyin(pvUser, &Hdr, sizeof(Hdr));
        if (RT_UNLIKELY(rc))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: copyin(%p,Hdr,) -> %#x; ulCmd=%#lx\n", pvUser, rc, ulCmd));
            return rc;
        }
        if (RT_UNLIKELY(Hdr.uVersion != VBGLREQHDR_VERSION))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: bad uVersion=%#x; ulCmd=%#lx\n", Hdr.uVersion, ulCmd));
            return EINVAL;
        }
        cbReq = RT_MAX(Hdr.cbIn, Hdr.cbOut);
        if (RT_UNLIKELY(   Hdr.cbIn < sizeof(Hdr)
                        || (Hdr.cbOut < sizeof(Hdr) && Hdr.cbOut != 0)
                        || cbReq > _1M*16))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: max(%#x,%#x); ulCmd=%#lx\n", Hdr.cbIn, Hdr.cbOut, ulCmd));
            return EINVAL;
        }

        /*
         * Allocate buffer and copy in the data.
         */
        pHdr = (PVBGLREQHDR)RTMemTmpAlloc(cbReq);
        if (RT_UNLIKELY(!pHdr))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: failed to allocate buffer of %d bytes; ulCmd=%#lx\n", cbReq, ulCmd));
            return ENOMEM;
        }
        rc = copyin(pvUser, pHdr, Hdr.cbIn);
        if (RT_UNLIKELY(rc))
        {
            LogRel(("vgdrvFreeBSDIOCtlSlow: copyin(%p,%p,%#x) -> %#x; ulCmd=%#lx\n",
                        pvUser, pHdr, Hdr.cbIn, rc, ulCmd));
            RTMemTmpFree(pHdr);
            return rc;
        }
        if (Hdr.cbIn < cbReq)
            RT_BZERO((uint8_t *)pHdr + Hdr.cbIn, cbReq - Hdr.cbIn);
    }
    else
    {
        Log(("vgdrvFreeBSDIOCtlSlow: huh? cbReq=%#x ulCmd=%#lx\n", cbReq, ulCmd));
        return EINVAL;
    }

    /*
     * Process the IOCtl.
     */
    int rc = VGDrvCommonIoCtl(ulCmd, &g_DevExt, pSession, pHdr, cbReq);
    if (RT_LIKELY(!rc))
    {
        /*
         * If unbuffered, copy back the result before returning.
         */
        if (pvUser)
        {
            uint32_t cbOut = pHdr->cbOut;
            if (cbOut > cbReq)
            {
                LogRel(("vgdrvFreeBSDIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cbReq, ulCmd));
                cbOut = cbReq;
            }
            rc = copyout(pHdr, pvUser, cbOut);
            if (RT_UNLIKELY(rc))
                LogRel(("vgdrvFreeBSDIOCtlSlow: copyout(%p,%p,%#x) -> %d; uCmd=%#lx!\n", pHdr, pvUser, cbOut, rc, ulCmd));

            Log(("vgdrvFreeBSDIOCtlSlow: returns %d / %d ulCmd=%lx\n", 0, pHdr->rc, ulCmd));

            /* cleanup */
            RTMemTmpFree(pHdr);
        }
    }
    else
    {
        /*
         * The request failed, just clean up.
         */
        if (pvUser)
            RTMemTmpFree(pHdr);

        Log(("vgdrvFreeBSDIOCtlSlow: ulCmd=%lx pData=%p failed, rc=%d\n", ulCmd, pvData, rc));
        rc = EINVAL;
    }

    return rc;
}
예제 #22
0
/**
 * Worker function for dbgfR3CoreWrite() which does the writing.
 *
 * @returns VBox status code
 * @param   pVM                 Pointer to the VM.
 * @param   hFile               The file to write to.  Caller closes this.
 */
static int dbgfR3CoreWriteWorker(PVM pVM, RTFILE hFile)
{
    /*
     * Collect core information.
     */
    uint32_t const cu32MemRanges = dbgfR3GetRamRangeCount(pVM);
    uint16_t const cMemRanges    = cu32MemRanges < UINT16_MAX - 1 ? cu32MemRanges : UINT16_MAX - 1; /* One PT_NOTE Program header */
    uint16_t const cProgHdrs     = cMemRanges + 1;

    DBGFCOREDESCRIPTOR CoreDescriptor;
    RT_ZERO(CoreDescriptor);
    CoreDescriptor.u32Magic           = DBGFCORE_MAGIC;
    CoreDescriptor.u32FmtVersion      = DBGFCORE_FMT_VERSION;
    CoreDescriptor.cbSelf             = sizeof(CoreDescriptor);
    CoreDescriptor.u32VBoxVersion     = VBOX_FULL_VERSION;
    CoreDescriptor.u32VBoxRevision    = VMMGetSvnRev();
    CoreDescriptor.cCpus              = pVM->cCpus;

    Log((DBGFLOG_NAME ": CoreDescriptor Version=%u Revision=%u\n", CoreDescriptor.u32VBoxVersion, CoreDescriptor.u32VBoxRevision));

    /*
     * Compute the file layout (see pg_dbgf_vmcore).
     */
    uint64_t const offElfHdr          = RTFileTell(hFile);
    uint64_t const offNoteSection     = offElfHdr         + sizeof(Elf64_Ehdr);
    uint64_t const offLoadSections    = offNoteSection    + sizeof(Elf64_Phdr);
    uint64_t const cbLoadSections     = cMemRanges * sizeof(Elf64_Phdr);
    uint64_t const offCoreDescriptor  = offLoadSections   + cbLoadSections;
    uint64_t const cbCoreDescriptor   = Elf64NoteSectionSize(g_pcszCoreVBoxCore, sizeof(CoreDescriptor));
    uint64_t const offCpuDumps        = offCoreDescriptor + cbCoreDescriptor;
    uint64_t const cbCpuDumps         = pVM->cCpus * Elf64NoteSectionSize(g_pcszCoreVBoxCpu, sizeof(DBGFCORECPU));
    uint64_t const offMemory          = offCpuDumps       + cbCpuDumps;

    uint64_t const offNoteSectionData = offCoreDescriptor;
    uint64_t const cbNoteSectionData  = cbCoreDescriptor + cbCpuDumps;

    /*
     * Write ELF header.
     */
    int rc = Elf64WriteElfHdr(hFile, cProgHdrs, 0 /* cSecHdrs */);
    if (RT_FAILURE(rc))
    {
        LogRel((DBGFLOG_NAME ": Elf64WriteElfHdr failed. rc=%Rrc\n", rc));
        return rc;
    }

    /*
     * Write PT_NOTE program header.
     */
    Assert(RTFileTell(hFile) == offNoteSection);
    rc = Elf64WriteProgHdr(hFile, PT_NOTE, PF_R,
                           offNoteSectionData,  /* file offset to contents */
                           cbNoteSectionData,   /* size in core file */
                           cbNoteSectionData,   /* size in memory */
                           0);                  /* physical address */
    if (RT_FAILURE(rc))
    {
        LogRel((DBGFLOG_NAME ": Elf64WritreProgHdr failed for PT_NOTE. rc=%Rrc\n", rc));
        return rc;
    }

    /*
     * Write PT_LOAD program header for each memory range.
     */
    Assert(RTFileTell(hFile) == offLoadSections);
    uint64_t offMemRange = offMemory;
    for (uint16_t iRange = 0; iRange < cMemRanges; iRange++)
    {
        RTGCPHYS    GCPhysStart;
        RTGCPHYS    GCPhysEnd;
        bool        fIsMmio;
        rc = PGMR3PhysGetRange(pVM, iRange, &GCPhysStart, &GCPhysEnd, NULL /* pszDesc */, &fIsMmio);
        if (RT_FAILURE(rc))
        {
            LogRel((DBGFLOG_NAME ": PGMR3PhysGetRange failed for iRange(%u) rc=%Rrc\n", iRange, rc));
            return rc;
        }

        uint64_t cbMemRange  = GCPhysEnd - GCPhysStart + 1;
        uint64_t cbFileRange = fIsMmio ? 0 : cbMemRange;

        Log((DBGFLOG_NAME ": PGMR3PhysGetRange iRange=%u GCPhysStart=%#x GCPhysEnd=%#x cbMemRange=%u\n",
             iRange, GCPhysStart, GCPhysEnd, cbMemRange));

        rc = Elf64WriteProgHdr(hFile, PT_LOAD, PF_R,
                               offMemRange,                         /* file offset to contents */
                               cbFileRange,                         /* size in core file */
                               cbMemRange,                          /* size in memory */
                               GCPhysStart);                        /* physical address */
        if (RT_FAILURE(rc))
        {
            LogRel((DBGFLOG_NAME ": Elf64WriteProgHdr failed for memory range(%u) cbFileRange=%u cbMemRange=%u rc=%Rrc\n",
                    iRange, cbFileRange, cbMemRange, rc));
            return rc;
        }

        offMemRange += cbFileRange;
    }

    /*
     * Write the Core descriptor note header and data.
     */
    Assert(RTFileTell(hFile) == offCoreDescriptor);
    rc = Elf64WriteNoteHdr(hFile, NT_VBOXCORE, g_pcszCoreVBoxCore, &CoreDescriptor, sizeof(CoreDescriptor));
    if (RT_FAILURE(rc))
    {
        LogRel((DBGFLOG_NAME ": Elf64WriteNoteHdr failed for Note '%s' rc=%Rrc\n", g_pcszCoreVBoxCore, rc));
        return rc;
    }

    /*
     * Write the CPU context note headers and data.
     */
    Assert(RTFileTell(hFile) == offCpuDumps);
    PDBGFCORECPU pDbgfCoreCpu = (PDBGFCORECPU)RTMemAlloc(sizeof(*pDbgfCoreCpu));
    if (RT_UNLIKELY(!pDbgfCoreCpu))
    {
        LogRel((DBGFLOG_NAME ": failed to alloc %u bytes for DBGFCORECPU\n", sizeof(*pDbgfCoreCpu)));
        return VERR_NO_MEMORY;
    }

    for (uint32_t iCpu = 0; iCpu < pVM->cCpus; iCpu++)
    {
        PVMCPU      pVCpu = &pVM->aCpus[iCpu];
        PCPUMCTX    pCtx  = CPUMQueryGuestCtxPtr(pVCpu);
        if (RT_UNLIKELY(!pCtx))
        {
            LogRel((DBGFLOG_NAME ": CPUMQueryGuestCtxPtr failed for vCPU[%u]\n", iCpu));
            RTMemFree(pDbgfCoreCpu);
            return VERR_INVALID_POINTER;
        }

        RT_BZERO(pDbgfCoreCpu, sizeof(*pDbgfCoreCpu));
        dbgfR3GetCoreCpu(pCtx, pDbgfCoreCpu);
        rc = Elf64WriteNoteHdr(hFile, NT_VBOXCPU, g_pcszCoreVBoxCpu, pDbgfCoreCpu, sizeof(*pDbgfCoreCpu));
        if (RT_FAILURE(rc))
        {
            LogRel((DBGFLOG_NAME ": Elf64WriteNoteHdr failed for vCPU[%u] rc=%Rrc\n", iCpu, rc));
            RTMemFree(pDbgfCoreCpu);
            return rc;
        }
    }
    RTMemFree(pDbgfCoreCpu);
    pDbgfCoreCpu = NULL;

    /*
     * Write memory ranges.
     */
    Assert(RTFileTell(hFile) == offMemory);
    for (uint16_t iRange = 0; iRange < cMemRanges; iRange++)
    {
        RTGCPHYS GCPhysStart;
        RTGCPHYS GCPhysEnd;
        bool     fIsMmio;
        rc = PGMR3PhysGetRange(pVM, iRange, &GCPhysStart, &GCPhysEnd, NULL /* pszDesc */, &fIsMmio);
        if (RT_FAILURE(rc))
        {
            LogRel((DBGFLOG_NAME ": PGMR3PhysGetRange(2) failed for iRange(%u) rc=%Rrc\n", iRange, rc));
            return rc;
        }

        if (fIsMmio)
            continue;

        /*
         * Write page-by-page of this memory range.
         *
         * The read function may fail on MMIO ranges, we write these as zero
         * pages for now (would be nice to have the VGA bits there though).
         */
        uint64_t cbMemRange  = GCPhysEnd - GCPhysStart + 1;
        uint64_t cPages      = cbMemRange >> PAGE_SHIFT;
        for (uint64_t iPage = 0; iPage < cPages; iPage++)
        {
            uint8_t abPage[PAGE_SIZE];
            rc = PGMPhysSimpleReadGCPhys(pVM, abPage, GCPhysStart + (iPage << PAGE_SHIFT),  sizeof(abPage));
            if (RT_FAILURE(rc))
            {
                if (rc != VERR_PGM_PHYS_PAGE_RESERVED)
                    LogRel((DBGFLOG_NAME ": PGMPhysRead failed for iRange=%u iPage=%u. rc=%Rrc. Ignoring...\n", iRange, iPage, rc));
                RT_ZERO(abPage);
            }

            rc = RTFileWrite(hFile, abPage, sizeof(abPage), NULL /* all */);
            if (RT_FAILURE(rc))
            {
                LogRel((DBGFLOG_NAME ": RTFileWrite failed. iRange=%u iPage=%u rc=%Rrc\n", iRange, iPage, rc));
                return rc;
            }
        }
    }

    return rc;
}
VBoxDnDDataObject::VBoxDnDDataObject(FORMATETC *pFormatEtc,
                                     STGMEDIUM *pStgMed, ULONG cFormats)
    : mStatus(Uninitialized),
      mRefCount(1),
      mcFormats(0),
      mpvData(NULL),
      mcbData(0)
{
    HRESULT hr;

    /* Make sure that there's enough room for our fixed formats. */
    ULONG cAllFormats = cFormats + 1;

    try
    {
        mpFormatEtc = new FORMATETC[cAllFormats];
        RT_BZERO(mpFormatEtc, sizeof(FORMATETC) * cAllFormats);
        mpStgMedium = new STGMEDIUM[cAllFormats];
        RT_BZERO(mpStgMedium, sizeof(STGMEDIUM) * cAllFormats);

        if (   pFormatEtc
            && pStgMed)
        {
            for (ULONG i = 0; i < cFormats; i++)
            {
                LogFlowFunc(("Format %RU32: cfFormat=%RI16, tyMed=%RU32, dwAspect=%RU32\n",
                             i, pFormatEtc[i].cfFormat, pFormatEtc[i].tymed, pFormatEtc[i].dwAspect));
                mpFormatEtc[i] = pFormatEtc[i];
                mpStgMedium[i] = pStgMed[i];
            }
        }

        hr = S_OK;
    }
    catch (std::bad_alloc &)
    {
        hr = E_OUTOFMEMORY;
    }

    if (SUCCEEDED(hr))
    {
        int rc2 = RTSemEventCreate(&mSemEvent);
        AssertRC(rc2);

        /* Most commonly used format. */
        RegisterFormat(&mpFormatEtc[cFormats], CF_HDROP);
        mpStgMedium[cFormats++].tymed = TYMED_HGLOBAL;
#if 0
        /* IStream. */
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR));
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_FILECONTENTS),
                       TYMED_ISTREAM, 0 /* lIndex */);

        /* Required for e.g. Windows Media Player. */
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_FILENAME));
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_FILENAMEW));
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_SHELLIDLIST));
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_SHELLIDLISTOFFSET));
#endif
        mcFormats = cFormats;
        mStatus = Initialized;
    }

    LogFlowFunc(("cFormats=%RU32, hr=%Rhrc\n", cFormats, hr));
}
예제 #24
0
/**
 * Device I/O Control entry point.
 *
 * @param   pFilp       Associated file pointer.
 * @param   uCmd        The function specified to ioctl().
 * @param   ulArg       The argument specified to ioctl().
 * @param   pSession    The session instance.
 */
static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg, PSUPDRVSESSION pSession)
{
    int                 rc;
    SUPREQHDR           Hdr;
    PSUPREQHDR          pHdr;
    uint32_t            cbBuf;

    Log6(("VBoxDrvLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p pid=%d/%d\n", pFilp, uCmd, (void *)ulArg, RTProcSelf(), current->pid));

    /*
     * Read the header.
     */
    if (RT_UNLIKELY(copy_from_user(&Hdr, (void *)ulArg, sizeof(Hdr))))
    {
        Log(("VBoxDrvLinuxIOCtl: copy_from_user(,%#lx,) failed; uCmd=%#x\n", ulArg, uCmd));
        return -EFAULT;
    }
    if (RT_UNLIKELY((Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC))
    {
        Log(("VBoxDrvLinuxIOCtl: bad header magic %#x; uCmd=%#x\n", Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, uCmd));
        return -EINVAL;
    }

    /*
     * Buffer the request.
     */
    cbBuf = RT_MAX(Hdr.cbIn, Hdr.cbOut);
    if (RT_UNLIKELY(cbBuf > _1M*16))
    {
        Log(("VBoxDrvLinuxIOCtl: too big cbBuf=%#x; uCmd=%#x\n", cbBuf, uCmd));
        return -E2BIG;
    }
    if (RT_UNLIKELY(_IOC_SIZE(uCmd) ? cbBuf != _IOC_SIZE(uCmd) : Hdr.cbIn < sizeof(Hdr)))
    {
        Log(("VBoxDrvLinuxIOCtl: bad ioctl cbBuf=%#x _IOC_SIZE=%#x; uCmd=%#x\n", cbBuf, _IOC_SIZE(uCmd), uCmd));
        return -EINVAL;
    }
    pHdr = RTMemAlloc(cbBuf);
    if (RT_UNLIKELY(!pHdr))
    {
        OSDBGPRINT(("VBoxDrvLinuxIOCtl: failed to allocate buffer of %d bytes for uCmd=%#x\n", cbBuf, uCmd));
        return -ENOMEM;
    }
    if (RT_UNLIKELY(copy_from_user(pHdr, (void *)ulArg, Hdr.cbIn)))
    {
        Log(("VBoxDrvLinuxIOCtl: copy_from_user(,%#lx, %#x) failed; uCmd=%#x\n", ulArg, Hdr.cbIn, uCmd));
        RTMemFree(pHdr);
        return -EFAULT;
    }
    if (Hdr.cbIn < cbBuf)
        RT_BZERO((uint8_t *)pHdr + Hdr.cbIn, cbBuf - Hdr.cbIn);

    /*
     * Process the IOCtl.
     */
    stac();
    rc = supdrvIOCtl(uCmd, &g_DevExt, pSession, pHdr, cbBuf);
    clac();

    /*
     * Copy ioctl data and output buffer back to user space.
     */
    if (RT_LIKELY(!rc))
    {
        uint32_t cbOut = pHdr->cbOut;
        if (RT_UNLIKELY(cbOut > cbBuf))
        {
            OSDBGPRINT(("VBoxDrvLinuxIOCtl: too much output! %#x > %#x; uCmd=%#x!\n", cbOut, cbBuf, uCmd));
            cbOut = cbBuf;
        }
        if (RT_UNLIKELY(copy_to_user((void *)ulArg, pHdr, cbOut)))
        {
            /* this is really bad! */
            OSDBGPRINT(("VBoxDrvLinuxIOCtl: copy_to_user(%#lx,,%#x); uCmd=%#x!\n", ulArg, cbOut, uCmd));
            rc = -EFAULT;
        }
    }
    else
    {
        Log(("VBoxDrvLinuxIOCtl: pFilp=%p uCmd=%#x ulArg=%p failed, rc=%d\n", pFilp, uCmd, (void *)ulArg, rc));
        rc = -EINVAL;
    }
    RTMemFree(pHdr);

    Log6(("VBoxDrvLinuxIOCtl: returns %d (pid=%d/%d)\n", rc, RTProcSelf(), current->pid));
    return rc;
}
/**
 * Get Parallel port address and update the shared data
 * structure.
 * @returns VBox status code.
 * @param   pThis    The host parallel port instance data.
 */
static int drvWinHostGetparportAddr(PDRVHOSTPARALLEL pThis)
{
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA DeviceInfoData;
    uint32_t u32Idx;
    uint32_t u32ParportAddr;
    int rc = VINF_SUCCESS;

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

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

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

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

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

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

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

    SetupDiDestroyDeviceInfoList(hDevInfo);
    return rc;

}
예제 #26
0
int MsixInit(PCPDMPCIHLP pPciHlp, PPCIDEVICE pDev, PPDMMSIREG pMsiReg)
{
    if (pMsiReg->cMsixVectors == 0)
         return VINF_SUCCESS;

     /* We cannot init MSI-X on raw devices yet. */
    Assert(!pciDevIsPassthrough(pDev));

    uint16_t   cVectors    = pMsiReg->cMsixVectors;
    uint8_t    iCapOffset  = pMsiReg->iMsixCapOffset;
    uint8_t    iNextOffset = pMsiReg->iMsixNextOffset;
    uint8_t    iBar        = pMsiReg->iMsixBar;

    if (cVectors > VBOX_MSIX_MAX_ENTRIES)
    {
        AssertMsgFailed(("Too many MSI-X vectors: %d\n", cVectors));
        return VERR_TOO_MUCH_DATA;
    }

    if (iBar > 5)
    {
        AssertMsgFailed(("Using wrong BAR for MSI-X: %d\n", iBar));
        return VERR_INVALID_PARAMETER;
    }

    Assert(iCapOffset != 0 && iCapOffset < 0xff && iNextOffset < 0xff);

    int rc = VINF_SUCCESS;

    /* If device is passthrough, BAR is registered using common mechanism. */
    if (!pciDevIsPassthrough(pDev))
    {
        rc = PDMDevHlpPCIIORegionRegister (pDev->pDevIns, iBar, 0x1000, PCI_ADDRESS_SPACE_MEM, msixMap);
        if (RT_FAILURE (rc))
            return rc;
    }

    pDev->Int.s.u8MsixCapOffset = iCapOffset;
    pDev->Int.s.u8MsixCapSize   = VBOX_MSIX_CAP_SIZE;
    PVM pVM = PDMDevHlpGetVM(pDev->pDevIns);

    pDev->Int.s.pMsixPageR3     = NULL;

    rc = MMHyperAlloc(pVM, 0x1000, 1, MM_TAG_PDM_DEVICE_USER, (void **)&pDev->Int.s.pMsixPageR3);
    if (RT_FAILURE(rc) || (pDev->Int.s.pMsixPageR3 == NULL))
        return VERR_NO_VM_MEMORY;
    RT_BZERO(pDev->Int.s.pMsixPageR3, 0x1000);
    pDev->Int.s.pMsixPageR0     = MMHyperR3ToR0(pVM, pDev->Int.s.pMsixPageR3);
    pDev->Int.s.pMsixPageRC     = MMHyperR3ToRC(pVM, pDev->Int.s.pMsixPageR3);

    /* R3 PCI helper */
    pDev->Int.s.pPciBusPtrR3    = pPciHlp;

    PCIDevSetByte(pDev,  iCapOffset + 0, VBOX_PCI_CAP_ID_MSIX);
    PCIDevSetByte(pDev,  iCapOffset + 1, iNextOffset); /* next */
    PCIDevSetWord(pDev,  iCapOffset + VBOX_MSIX_CAP_MESSAGE_CONTROL, cVectors - 1);

    uint32_t offTable = 0, offPBA = 0x800;

    PCIDevSetDWord(pDev,  iCapOffset + VBOX_MSIX_TABLE_BIROFFSET, offTable | iBar);
    PCIDevSetDWord(pDev,  iCapOffset + VBOX_MSIX_PBA_BIROFFSET,   offPBA   | iBar);

    pciDevSetMsixCapable(pDev);

    return VINF_SUCCESS;
}
예제 #27
0
void tstFileAioTestReadWriteBasic(RTFILE File, bool fWrite, void *pvTestBuf,
                                  size_t cbTestBuf, size_t cbTestFile, uint32_t cMaxReqsInFlight)
{
    /* Allocate request array. */
    RTFILEAIOREQ *paReqs;
    paReqs = (PRTFILEAIOREQ)RTTestGuardedAllocHead(g_hTest, cMaxReqsInFlight * sizeof(RTFILEAIOREQ));
    RTTESTI_CHECK_RETV(paReqs);
    RT_BZERO(paReqs, sizeof(cMaxReqsInFlight * sizeof(RTFILEAIOREQ)));

    /* Allocate array holding pointer to data buffers. */
    void **papvBuf = (void **)RTTestGuardedAllocHead(g_hTest, cMaxReqsInFlight * sizeof(void *));
    RTTESTI_CHECK_RETV(papvBuf);

    /* Allocate the buffers*/
    for (unsigned i = 0; i < cMaxReqsInFlight; i++)
    {
        RTTESTI_CHECK_RC_OK_RETV(RTTestGuardedAlloc(g_hTest, cbTestBuf, PAGE_SIZE, true /*fHead*/, &papvBuf[i]));
        if (fWrite)
            memcpy(papvBuf[i], pvTestBuf, cbTestBuf);
        if (fWrite)
            memcpy(papvBuf[i], pvTestBuf, cbTestBuf);
        else
            RT_BZERO(papvBuf[i], cbTestBuf);
    }

    /* Allocate array holding completed requests. */
    RTFILEAIOREQ *paReqsCompleted;
    paReqsCompleted = (PRTFILEAIOREQ)RTTestGuardedAllocHead(g_hTest, cMaxReqsInFlight * sizeof(RTFILEAIOREQ));
    RTTESTI_CHECK_RETV(paReqsCompleted);
    RT_BZERO(paReqsCompleted, cMaxReqsInFlight * sizeof(RTFILEAIOREQ));

    /* Create a context and associate the file handle with it. */
    RTFILEAIOCTX hAioContext;
    RTTESTI_CHECK_RC_RETV(RTFileAioCtxCreate(&hAioContext, cMaxReqsInFlight, 0 /* fFlags */), VINF_SUCCESS);
    RTTESTI_CHECK_RC_RETV(RTFileAioCtxAssociateWithFile(hAioContext, File), VINF_SUCCESS);

    /* Initialize requests. */
    for (unsigned i = 0; i < cMaxReqsInFlight; i++)
        RTFileAioReqCreate(&paReqs[i]);

    RTFOFF      off    = 0;
    int         cRuns  = 0;
    uint64_t    NanoTS = RTTimeNanoTS();
    size_t      cbLeft = cbTestFile;
    while (cbLeft)
    {
        int rc;
        int cReqs = 0;
        for (unsigned i = 0; i < cMaxReqsInFlight; i++)
        {
            size_t cbTransfer = cbLeft < cbTestBuf ? cbLeft : cbTestBuf;
            if (!cbTransfer)
                break;

            if (fWrite)
                rc = RTFileAioReqPrepareWrite(paReqs[i], File, off, papvBuf[i],
                                              cbTransfer, papvBuf[i]);
            else
                rc = RTFileAioReqPrepareRead(paReqs[i], File, off, papvBuf[i],
                                             cbTransfer, papvBuf[i]);
            RTTESTI_CHECK_RC(rc, VINF_SUCCESS);

            cbLeft -= cbTransfer;
            off    += cbTransfer;
            cReqs++;
        }

        rc = RTFileAioCtxSubmit(hAioContext, paReqs, cReqs);
        RTTESTI_CHECK_MSG(rc == VINF_SUCCESS, ("Failed to submit tasks after %d runs. rc=%Rrc\n", cRuns, rc));
        if (rc != VINF_SUCCESS)
            break;

        /* Wait */
        uint32_t cCompleted = 0;
        RTTESTI_CHECK_RC(rc = RTFileAioCtxWait(hAioContext, cReqs, RT_INDEFINITE_WAIT,
                                               paReqsCompleted, cMaxReqsInFlight, &cCompleted),
                         VINF_SUCCESS);
        if (rc != VINF_SUCCESS)
            break;

        if (!fWrite)
        {
            for (uint32_t i = 0; i < cCompleted; i++)
            {
                /* Compare that we read the right stuff. */
                void *pvBuf = RTFileAioReqGetUser(paReqsCompleted[i]);
                RTTESTI_CHECK(pvBuf);

                size_t cbTransfered;
                RTTESTI_CHECK_RC(rc = RTFileAioReqGetRC(paReqsCompleted[i], &cbTransfered), VINF_SUCCESS);
                if (rc != VINF_SUCCESS)
                    break;
                RTTESTI_CHECK_MSG(cbTransfered == cbTestBuf, ("cbTransfered=%zd\n", cbTransfered));
                RTTESTI_CHECK_RC_OK(rc = (memcmp(pvBuf, pvTestBuf, cbTestBuf) == 0 ? VINF_SUCCESS : VERR_BAD_EXE_FORMAT));
                if (rc != VINF_SUCCESS)
                    break;
                memset(pvBuf, 0, cbTestBuf);
            }
        }
        cRuns++;
        if (RT_FAILURE(rc))
            break;
    }

    NanoTS = RTTimeNanoTS() - NanoTS;
    uint64_t SpeedKBs = (uint64_t)(cbTestFile / (NanoTS / 1000000000.0) / 1024);
    RTTestValue(g_hTest, "Throughput", SpeedKBs, RTTESTUNIT_KILOBYTES_PER_SEC);

    /* cleanup */
    for (unsigned i = 0; i < cMaxReqsInFlight; i++)
        RTTestGuardedFree(g_hTest, papvBuf[i]);
    RTTestGuardedFree(g_hTest, papvBuf);
    for (unsigned i = 0; i < cMaxReqsInFlight; i++)
        RTTESTI_CHECK_RC(RTFileAioReqDestroy(paReqs[i]), VINF_SUCCESS);
    RTTESTI_CHECK_RC(RTFileAioCtxDestroy(hAioContext), VINF_SUCCESS);
    RTTestGuardedFree(g_hTest, paReqs);
}
예제 #28
0
RTDECL(int) RTAsn1ContentReallocZ(PRTASN1CORE pAsn1Core, size_t cb, PCRTASN1ALLOCATORVTABLE pAllocator)
{
    /* Validate input. */
    AssertPtr(pAsn1Core);
    AssertReturn(cb < _1G, VERR_INVALID_PARAMETER);

    if (cb > 0)
    {
        /*
         * Case 1 - Initial allocation.
         */
        uint32_t cbNeeded  = RT_OFFSETOF(RTASN1MEMCONTENT, au64Content) + (uint32_t)cb;
        if (!(pAsn1Core->fFlags & RTASN1CORE_F_ALLOCATED_CONTENT))
            return RTAsn1ContentAllocZ(pAsn1Core, cb, pAllocator);

        /* Locate the header. */
        PRTASN1MEMCONTENT pHdr = RT_FROM_MEMBER(pAsn1Core->uData.pv, RTASN1MEMCONTENT, au64Content);

        /*
         * Case 2 - Reallocation using the same allocator.
         */
        if (   pHdr->Allocation.pAllocator == pAllocator
            || !pAllocator)
        {
            pHdr->Allocation.cReallocs++;

            /* Modify the allocation if necessary. */
            if (pHdr->Allocation.cbAllocated < cbNeeded)
            {
                RTASN1ALLOCATION Allocation = pHdr->Allocation;
                int rc = Allocation.pAllocator->pfnRealloc(Allocation.pAllocator, &Allocation, pHdr, (void **)&pHdr, cbNeeded);
                if (RT_FAILURE(rc))
                    return rc;
                Assert(Allocation.cbAllocated >= cbNeeded);
                pAsn1Core->uData.pv = &pHdr->au64Content[0];
                pHdr->Allocation    = Allocation;
            }

            /* Clear any additional memory we're letting the user use and
               update the content size. */
            if (pAsn1Core->cb < cb)
                RT_BZERO((uint8_t *)&pAsn1Core->uData.pu8[pAsn1Core->cb], cb - pAsn1Core->cb);
            pAsn1Core->cb = (uint32_t)cb;
        }
        /*
         * Case 3 - Reallocation using a different allocator.
         */
        else
        {
            /* Initialize the temporary allocation tracker. */
            RTASN1ALLOCATION Allocation;
            Allocation.cbAllocated = 0;
            Allocation.cReallocs   = pHdr->Allocation.cReallocs + 1;
            Allocation.uReserved0  = 0;
            Allocation.pAllocator  = pAllocator;

            /* Make the allocation. */
            PRTASN1MEMCONTENT pHdrNew;
            int rc = pAllocator->pfnAlloc(pAllocator, &Allocation, (void **)&pHdrNew, cbNeeded);
            if (RT_FAILURE(rc))
                return rc;
            Assert(Allocation.cbAllocated >= cbNeeded);

            /* Duplicate the old content and zero any new memory we might've added. */
            if (pAsn1Core->cb >= cb)
                memcpy(&pHdrNew->au64Content[0], &pHdr->au64Content[0], cb);
            else
            {
                memcpy(&pHdrNew->au64Content[0], &pHdr->au64Content[0], pAsn1Core->cb);
                RT_BZERO((uint8_t *)&pHdrNew->au64Content[0] + pAsn1Core->cb, cb - pAsn1Core->cb);
            }

            /* Update the core. */
            pHdrNew->Allocation = Allocation;
            pAsn1Core->uData.pv = &pHdrNew->au64Content[0];
            pAsn1Core->fFlags  |= RTASN1CORE_F_ALLOCATED_CONTENT; /* free cleared it. */
            pAsn1Core->cb       = (uint32_t)cb;

            /* Free the old content. */
            Allocation = pHdr->Allocation;
            Allocation.pAllocator->pfnFree(Allocation.pAllocator, &Allocation, pHdr);
            Assert(Allocation.cbAllocated == 0);
        }
    }
    /*
     * Case 4 - It's a request to free the memory.
     */
    else
        RTAsn1ContentFree(pAsn1Core);
    return VINF_SUCCESS;
}
예제 #29
0
UIDnDDataObject::UIDnDDataObject(UIDnDHandler *pDnDHandler, const QStringList &lstFormats)
    : m_pDnDHandler(pDnDHandler)
    , m_enmStatus(DnDDataObjectStatus_Uninitialized)
    , m_cRefs(1)
    , m_cFormats(0)
    , m_pFormatEtc(NULL)
    , m_pStgMedium(NULL)
    , m_SemEvent(NIL_RTSEMEVENT)
    , m_fDataRetrieved(false)
    , m_pvData(NULL)
    , m_cbData(0)
{
    HRESULT hr;

    ULONG cMaxFormats        = 16; /* Maximum number of registered formats. */
    ULONG cRegisteredFormats = 0;

    try
    {
        m_pFormatEtc = new FORMATETC[cMaxFormats];
        RT_BZERO(m_pFormatEtc, sizeof(FORMATETC) * cMaxFormats);
        m_pStgMedium = new STGMEDIUM[cMaxFormats];
        RT_BZERO(m_pStgMedium, sizeof(STGMEDIUM) * cMaxFormats);

        for (int i = 0;
             (   i < lstFormats.size()
              && i < cMaxFormats); i++)
        {
            const QString &strFormat = lstFormats.at(i);
            if (m_lstFormats.contains(strFormat))
                continue;

            /* URI data ("text/uri-list"). */
            if (strFormat.contains("text/uri-list", Qt::CaseInsensitive))
            {
                RegisterFormat(&m_pFormatEtc[cRegisteredFormats], CF_TEXT);
                m_pStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
                RegisterFormat(&m_pFormatEtc[cRegisteredFormats], CF_UNICODETEXT);
                m_pStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
                RegisterFormat(&m_pFormatEtc[cRegisteredFormats], CF_HDROP);
                m_pStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;

                m_lstFormats << strFormat;
            }
            /* Plain text ("text/plain"). */
            if (strFormat.contains("text/plain", Qt::CaseInsensitive))
            {
                RegisterFormat(&m_pFormatEtc[cRegisteredFormats], CF_TEXT);
                m_pStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;
                RegisterFormat(&m_pFormatEtc[cRegisteredFormats], CF_UNICODETEXT);
                m_pStgMedium[cRegisteredFormats++].tymed = TYMED_HGLOBAL;

                m_lstFormats << strFormat;
            }
        }

        LogRel3(("DnD: Total registered native formats: %RU32 (for %d formats from guest)\n",
                 cRegisteredFormats, lstFormats.size()));
        hr = S_OK;
    }
    catch (std::bad_alloc &)
    {
        hr = E_OUTOFMEMORY;
    }

    if (SUCCEEDED(hr))
    {
        int rc2 = RTSemEventCreate(&m_SemEvent);
        AssertRC(rc2);

        /*
         * Other (not so common) formats.
         */
#if 0
        /* IStream. */
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR));
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_FILECONTENTS),
                       TYMED_ISTREAM, 0 /* lIndex */);

        /* Required for e.g. Windows Media Player. */
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_FILENAME));
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_FILENAMEW));
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_SHELLIDLIST));
        RegisterFormat(&mpFormatEtc[cFormats++],
                       RegisterClipboardFormat(CFSTR_SHELLIDLISTOFFSET));
#endif
        m_cFormats  = cRegisteredFormats;
        m_enmStatus = DnDDataObjectStatus_Dropping;
    }

    LogFlowFunc(("hr=%Rhrc\n", hr));
}
예제 #30
0
/**
 * @interface_method_impl{DBGFOSIDMESG,pfnQueryKernelLog}
 */
static DECLCALLBACK(int) dbgDiggerLinuxIDmsg_QueryKernelLog(PDBGFOSIDMESG pThis, PUVM pUVM, uint32_t fFlags, uint32_t cMessages,
                                                            char *pszBuf, size_t cbBuf, size_t *pcbActual)
{
    PDBGDIGGERLINUX pData = RT_FROM_MEMBER(pThis, DBGDIGGERLINUX, IDmesg);

    if (cMessages < 1)
        return VERR_INVALID_PARAMETER;

    /*
     * Resolve the symbols we need and read their values.
     */
    RTDBGAS  hAs = DBGFR3AsResolveAndRetain(pUVM, DBGF_AS_KERNEL);
    RTDBGMOD hMod;
    int rc = RTDbgAsModuleByName(hAs, "vmlinux", 0, &hMod);
    if (RT_FAILURE(rc))
        return VERR_NOT_FOUND;
    RTDbgAsRelease(hAs);

    RTGCPTR  GCPtrLogBuf;
    uint32_t cbLogBuf;
    uint32_t idxFirst;
    uint32_t idxNext;

    struct { void *pvVar; size_t cbHost, cbGuest; const char *pszSymbol; } aSymbols[] =
    {
        { &GCPtrLogBuf, sizeof(GCPtrLogBuf),    pData->f64Bit ? sizeof(uint64_t) : sizeof(uint32_t),   "log_buf" },
        { &cbLogBuf,    sizeof(cbLogBuf),       sizeof(cbLogBuf),                                      "log_buf_len" },
        { &idxFirst,    sizeof(idxFirst),       sizeof(idxFirst),                                      "log_first_idx" },
        { &idxNext,     sizeof(idxNext),        sizeof(idxNext),                                       "log_next_idx" },
    };
    for (uint32_t i = 0; i < RT_ELEMENTS(aSymbols); i++)
    {
        RTDBGSYMBOL SymInfo;
        rc = RTDbgModSymbolByName(hMod, aSymbols[i].pszSymbol, &SymInfo);
        if (RT_SUCCESS(rc))
        {
            RT_BZERO(aSymbols[i].pvVar, aSymbols[i].cbHost);
            Assert(aSymbols[i].cbHost >= aSymbols[i].cbGuest);
            DBGFADDRESS Addr;
            rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/,
                               DBGFR3AddrFromFlat(pUVM, &Addr, (RTGCPTR)SymInfo.Value + pData->AddrKernelBase.FlatPtr),
                               aSymbols[i].pvVar,  aSymbols[i].cbGuest);
            if (RT_SUCCESS(rc))
                continue;
            Log(("dbgDiggerLinuxIDmsg_QueryKernelLog: Reading '%s' at %RGv: %Rrc\n", aSymbols[i].pszSymbol, Addr.FlatPtr, rc));
        }
        else
            Log(("dbgDiggerLinuxIDmsg_QueryKernelLog: Error looking up '%s': %Rrc\n", aSymbols[i].pszSymbol, rc));
        RTDbgModRelease(hMod);
        return VERR_NOT_FOUND;
    }

    /*
     * Check if the values make sense.
     */
    if (pData->f64Bit ? !LNX64_VALID_ADDRESS(GCPtrLogBuf) : !LNX32_VALID_ADDRESS(GCPtrLogBuf))
    {
        Log(("dbgDiggerLinuxIDmsg_QueryKernelLog: 'log_buf' value %RGv is not valid.\n", GCPtrLogBuf));
        return VERR_NOT_FOUND;
    }
    if (   cbLogBuf < 4096
        || !RT_IS_POWER_OF_TWO(cbLogBuf)
        || cbLogBuf > 16*_1M)
    {
        Log(("dbgDiggerLinuxIDmsg_QueryKernelLog: 'log_buf_len' value %#x is not valid.\n", cbLogBuf));
        return VERR_NOT_FOUND;
    }
    uint32_t const cbLogAlign = 4;
    if (   idxFirst > cbLogBuf - sizeof(LNXPRINTKHDR)
        || (idxFirst & (cbLogAlign - 1)) != 0)
    {
        Log(("dbgDiggerLinuxIDmsg_QueryKernelLog: 'log_first_idx' value %#x is not valid.\n", idxFirst));
        return VERR_NOT_FOUND;
    }
    if (   idxNext > cbLogBuf - sizeof(LNXPRINTKHDR)
        || (idxNext & (cbLogAlign - 1)) != 0)
    {
        Log(("dbgDiggerLinuxIDmsg_QueryKernelLog: 'log_next_idx' value %#x is not valid.\n", idxNext));
        return VERR_NOT_FOUND;
    }

    /*
     * Read the whole log buffer.
     */
    uint8_t *pbLogBuf = (uint8_t *)RTMemAlloc(cbLogBuf);
    if (!pbLogBuf)
    {
        Log(("dbgDiggerLinuxIDmsg_QueryKernelLog: Failed to allocate %#x bytes for log buffer\n", cbLogBuf));
        return VERR_NO_MEMORY;
    }
    DBGFADDRESS Addr;
    rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, DBGFR3AddrFromFlat(pUVM, &Addr, GCPtrLogBuf), pbLogBuf, cbLogBuf);
    if (RT_FAILURE(rc))
    {
        Log(("dbgDiggerLinuxIDmsg_QueryKernelLog: Error reading %#x bytes of log buffer at %RGv: %Rrc\n",
             cbLogBuf, Addr.FlatPtr, rc));
        RTMemFree(pbLogBuf);
        return VERR_NOT_FOUND;
    }

    /*
     * Count the messages in the buffer while doing some basic validation.
     */
    uint32_t const cbUsed = idxFirst == idxNext ? cbLogBuf /* could be empty... */
                          : idxFirst < idxNext  ? idxNext - idxFirst : cbLogBuf - idxFirst + idxNext;
    uint32_t cbLeft    = cbUsed;
    uint32_t offCur    = idxFirst;
    uint32_t cLogMsgs  = 0;

    while (cbLeft > 0)
    {
        PCLNXPRINTKHDR pHdr = (PCLNXPRINTKHDR)&pbLogBuf[offCur];
        if (!pHdr->cbTotal)
        {
            /* Wrap around packet, most likely... */
            if (cbLogBuf - offCur >= cbLeft)
                break;
            offCur = 0;
            pHdr = (PCLNXPRINTKHDR)&pbLogBuf[offCur];
        }
        if (RT_UNLIKELY(   pHdr->cbTotal > cbLogBuf - sizeof(*pHdr) - offCur
                        || pHdr->cbTotal > cbLeft
                        || (pHdr->cbTotal & (cbLogAlign - 1)) != 0
                        || pHdr->cbTotal < (uint32_t)pHdr->cbText + (uint32_t)pHdr->cbDict + sizeof(*pHdr) ))
        {
            Log(("dbgDiggerLinuxIDmsg_QueryKernelLog: Invalid printk_log record at %#x: cbTotal=%#x cbText=%#x cbDict=%#x cbLogBuf=%#x cbLeft=%#x\n",
                 offCur, pHdr->cbTotal, pHdr->cbText, pHdr->cbDict, cbLogBuf, cbLeft));
            rc = VERR_INVALID_STATE;
            break;
        }

        if (pHdr->cbText > 0)
            cLogMsgs++;

        /* next */
        offCur += pHdr->cbTotal;
        cbLeft -= pHdr->cbTotal;
    }
    if (RT_FAILURE(rc))
    {
        RTMemFree(pbLogBuf);
        return rc;
    }

    /*
     * Copy the messages into the output buffer.
     */
    offCur = idxFirst;
    cbLeft = cbUsed;

    /* Skip messages that the caller doesn't want. */
    if (cMessages < cLogMsgs)
    {
        uint32_t cToSkip = cLogMsgs - cMessages;
        while (cToSkip > 0)
        {
            PCLNXPRINTKHDR pHdr = (PCLNXPRINTKHDR)&pbLogBuf[offCur];
            if (!pHdr->cbTotal)
            {
                offCur = 0;
                pHdr = (PCLNXPRINTKHDR)&pbLogBuf[offCur];
            }
            if (pHdr->cbText > 0)
                cToSkip--;

            /* next */
            offCur += pHdr->cbTotal;
            cbLeft -= pHdr->cbTotal;
        }
    }

    /* Now copy the messages. */
    size_t offDst = 0;
    while (cbLeft > 0)
    {
        PCLNXPRINTKHDR pHdr = (PCLNXPRINTKHDR)&pbLogBuf[offCur];
        if (!pHdr->cbTotal)
        {
            if (cbLogBuf - offCur >= cbLeft)
                break;
            offCur = 0;
            pHdr = (PCLNXPRINTKHDR)&pbLogBuf[offCur];
        }

        if (pHdr->cbText > 0)
        {
            char  *pchText = (char *)(pHdr + 1);
            size_t cchText = RTStrNLen(pchText, pHdr->cbText);
            if (offDst + cchText < cbBuf)
            {
                memcpy(&pszBuf[offDst], pHdr + 1, cchText);
                pszBuf[offDst + cchText] = '\n';
            }
            else if (offDst < cbBuf)
                memcpy(&pszBuf[offDst], pHdr + 1, cbBuf - offDst);
            offDst += cchText + 1;
        }

        /* next */
        offCur += pHdr->cbTotal;
        cbLeft -= pHdr->cbTotal;
    }

    /* Done with the buffer. */
    RTMemFree(pbLogBuf);

    /* Make sure we've reserved a char for the terminator. */
    if (!offDst)
        offDst = 1;

    /* Set return size value. */
    if (pcbActual)
        *pcbActual = offDst;

    /*
     * All VBox strings are UTF-8 and bad things may in theory happen if we
     * pass bad UTF-8 to code which assumes it's all valid.  So, we enforce
     * UTF-8 upon the guest kernel messages here even if they (probably) have
     * no defined code set in reality.
     */
    if (offDst <= cbBuf)
    {
        pszBuf[offDst - 1] = '\0';
        RTStrPurgeEncoding(pszBuf);
        return VINF_SUCCESS;
    }

    if (cbBuf)
    {
        pszBuf[cbBuf - 1] = '\0';
        RTStrPurgeEncoding(pszBuf);
    }
    return VERR_BUFFER_OVERFLOW;
}