static LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LRESULT rc = 0;

    VBOXCLIPBOARDCONTEXT *pCtx = &g_ctx;

    switch (msg)
    {
        case WM_CHANGECBCHAIN:
        {
            Log(("WM_CHANGECBCHAIN\n"));

            HWND hwndRemoved = (HWND)wParam;
            HWND hwndNext    = (HWND)lParam;

            if (hwndRemoved == pCtx->hwndNextInChain)
            {
                /* The window that was next to our in the chain is being removed.
                 * Relink to the new next window.
                 */
                pCtx->hwndNextInChain = hwndNext;
            }
            else
            {
                if (pCtx->hwndNextInChain)
                {
                    /* Pass the message further. */
                    DWORD_PTR dwResult;
                    rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
                    if (!rc)
                        rc = (LRESULT)dwResult;
                }
            }
        } break;

        case WM_DRAWCLIPBOARD:
        {
            Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->hwndNextInChain));

            if (GetClipboardOwner () != hwnd)
            {
                /* Clipboard was updated by another application. */
                vboxClipboardChanged (pCtx);
            }

            if (pCtx->hwndNextInChain)
            {
                /* Pass the message to next windows in the clipboard chain. */
                DWORD_PTR dwResult;
                rc = SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
                if (!rc)
                    rc = dwResult;
            }
        } break;

        case WM_TIMER:
        {
            HWND hViewer = GetClipboardViewer();

            /* Re-register ourselves in the clipboard chain if our last ping
             * timed out or there seems to be no valid chain. */
            if (!hViewer || pCtx->fCBChainPingInProcess)
            {
                removeFromCBChain(pCtx);
                addToCBChain(pCtx);
            }
            /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
             * processed by ourselves to the chain. */
            pCtx->fCBChainPingInProcess = TRUE;
            hViewer = GetClipboardViewer();
            if (hViewer)
                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, CBChainPingProc, (ULONG_PTR) pCtx);
        } break;

        case WM_CLOSE:
        {
            /* Do nothing. Ignore the message. */
        } break;

        case WM_RENDERFORMAT:
        {
            /* Insert the requested clipboard format data into the clipboard. */
            uint32_t u32Format = 0;

            UINT format = (UINT)wParam;

            Log(("WM_RENDERFORMAT %d\n", format));

            switch (format)
            {
                case CF_UNICODETEXT:
                    u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
                    break;

                case CF_DIB:
                    u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
                    break;

                default:
                    if (format >= 0xC000)
                    {
                        TCHAR szFormatName[256];

                        int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));

                        if (cActual)
                        {
                            if (strcmp (szFormatName, "HTML Format") == 0)
                            {
                                u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
                            }
                        }
                    }
                    break;
            }

            if (u32Format == 0 || pCtx->pClient == NULL)
            {
                /* Unsupported clipboard format is requested. */
                Log(("WM_RENDERFORMAT unsupported format requested or client is not active.\n"));
                EmptyClipboard ();
            }
            else
            {
                int vboxrc = vboxClipboardReadDataFromClient (pCtx, u32Format);

                dprintf(("vboxClipboardReadDataFromClient vboxrc = %d\n", vboxrc));

                if (   RT_SUCCESS (vboxrc)
                    && pCtx->pClient->data.pv != NULL
                    && pCtx->pClient->data.cb > 0
                    && pCtx->pClient->data.u32Format == u32Format)
                {
                    HANDLE hMem = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, pCtx->pClient->data.cb);

                    dprintf(("hMem %p\n", hMem));

                    if (hMem)
                    {
                        void *pMem = GlobalLock (hMem);

                        dprintf(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem)));

                        if (pMem)
                        {
                            Log(("WM_RENDERFORMAT setting data\n"));

                            if (pCtx->pClient->data.pv)
                            {
                                memcpy (pMem, pCtx->pClient->data.pv, pCtx->pClient->data.cb);

                                RTMemFree (pCtx->pClient->data.pv);
                                pCtx->pClient->data.pv        = NULL;
                            }

                            pCtx->pClient->data.cb        = 0;
                            pCtx->pClient->data.u32Format = 0;

                            /* The memory must be unlocked before inserting to the Clipboard. */
                            GlobalUnlock (hMem);

                            /* 'hMem' contains the host clipboard data.
                             * size is 'cb' and format is 'format'.
                             */
                            HANDLE hClip = SetClipboardData (format, hMem);

                            dprintf(("vboxClipboardHostEvent hClip %p\n", hClip));

                            if (hClip)
                            {
                                /* The hMem ownership has gone to the system. Nothing to do. */
                                break;
                            }
                        }

                        GlobalFree (hMem);
                    }
                }

                RTMemFree (pCtx->pClient->data.pv);
                pCtx->pClient->data.pv        = NULL;
                pCtx->pClient->data.cb        = 0;
                pCtx->pClient->data.u32Format = 0;

                /* Something went wrong. */
                EmptyClipboard ();
            }
        } break;

        case WM_RENDERALLFORMATS:
        {
            Log(("WM_RENDERALLFORMATS\n"));

            /* Do nothing. The clipboard formats will be unavailable now, because the
             * windows is to be destroyed and therefore the guest side becomes inactive.
             */
            if (OpenClipboard (hwnd))
            {
                EmptyClipboard();

                CloseClipboard();
            }
        } break;

        case WM_USER:
        {
            if (pCtx->pClient == NULL || pCtx->pClient->fMsgFormats)
            {
                /* Host has pending formats message. Ignore the guest announcement,
                 * because host clipboard has more priority.
                 */
                break;
            }

            /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
            uint32_t u32Formats = (uint32_t)lParam;

            Log(("WM_USER u32Formats = %02X\n", u32Formats));

            if (OpenClipboard (hwnd))
            {
                EmptyClipboard();

                Log(("WM_USER emptied clipboard\n"));

                HANDLE hClip = NULL;

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
                {
                    dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n"));

                    hClip = SetClipboardData (CF_UNICODETEXT, NULL);
                }

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
                {
                    dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));

                    hClip = SetClipboardData (CF_DIB, NULL);
                }

                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
                {
                    UINT format = RegisterClipboardFormat ("HTML Format");
                    dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_HTML 0x%04X\n", format));
                    if (format != 0)
                    {
                        hClip = SetClipboardData (format, NULL);
                    }
                }

                CloseClipboard();

                dprintf(("window proc WM_USER: hClip %p, err %d\n", hClip, GetLastError ()));
            }
            else
            {
                dprintf(("window proc WM_USER: failed to open clipboard\n"));
            }
        } break;

        default:
        {
            Log(("WM_ %p\n", msg));
            rc = DefWindowProc (hwnd, msg, wParam, lParam);
        }
    }

    Log(("WM_ rc %d\n", rc));
    return rc;
}
Пример #2
0
STDMETHODIMP VBoxDnDDropTarget::Drop(IDataObject *pDataObject,
                                     DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
    AssertPtrReturn(pDataObject, E_INVALIDARG);
    AssertPtrReturn(pdwEffect, E_INVALIDARG);

#ifdef DEBUG
    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));
#endif
    HRESULT hr = S_OK;

    if (mFormatEtc.cfFormat) /* Did we get a supported format yet? */
    {
        /* Make sure the data object's data format is still the same
         * as we got it in DragEnter(). */
        hr = pDataObject->QueryGetData(&mFormatEtc);
        AssertMsg(SUCCEEDED(hr),
                  ("Data format changed 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_UNICODETEXT:
                    {
                        AssertPtr(pvData);
                        size_t cbSize = GlobalSize(pvData);
                        LogFlowFunc(("CF_UNICODETEXT 0x%p got %zu bytes\n", pvData, cbSize));
                        if (cbSize)
                        {
                            char *pszText = NULL;
                            rc = RTUtf16ToUtf8((PCRTUTF16)pvData, &pszText);
                            if (RT_SUCCESS(rc))
                            {
                                mpvData = (void *)pszText;
                                mcbData = strlen(pszText) + 1; /* Include termination. */

                                /* Note: Don't free data of pszText, mpvData now owns it. */
                            }
                        }

                        break;
                    }

                    case CF_TEXT:
                    {
                        AssertPtr(pvData);
                        size_t cbSize = GlobalSize(pvData);
                        LogFlowFunc(("CF_TEXT 0x%p got %zu bytes\n", pvData, cbSize));
                        if (cbSize)
                        {
                            char *pszText = NULL;
                            rc = RTStrCurrentCPToUtf8(&pszText, (char *)pvData);
                            if (RT_SUCCESS(rc))
                            {
                                mpvData = (void *)pszText;
                                mcbData = strlen(pszText) + 1; /* Include termination. */

                                /* Note: Don't free data of pszText, mpvData now owns it. */
                            }
                        }

                        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));
                                    int rc2 = RTUtf16ToUtf8(pwszFile, &pszFile);
                                    AssertRC(rc2);
                                }
                                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)
                                RTMemFree(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;
}
Пример #3
0
RTDECL(int) RTSemRWDestroy(RTSEMRW hRWSem)
{
    struct RTSEMRWINTERNAL *pThis = hRWSem;

    /*
     * Validate handle.
     */
    if (pThis == NIL_RTSEMRW)
        return VINF_SUCCESS;
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    AssertReturn(pThis->u32Magic == RTSEMRW_MAGIC, VERR_INVALID_HANDLE);

    /*
     * Check if busy.
     */
    int rc = RTCritSectTryEnter(&pThis->CritSect);
    if (RT_SUCCESS(rc))
    {
        if (!pThis->cReads && !pThis->cWrites)
        {
            /*
             * Make it invalid and unusable.
             */
            ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMRW_MAGIC);
            pThis->cReads = ~0;

            /*
             * Do actual cleanup. None of these can now fail.
             */
            rc = RTSemEventMultiDestroy(pThis->ReadEvent);
            AssertMsgRC(rc, ("RTSemEventMultiDestroy failed! rc=%Rrc\n", rc));
            pThis->ReadEvent = NIL_RTSEMEVENTMULTI;

            rc = RTSemEventDestroy(pThis->WriteEvent);
            AssertMsgRC(rc, ("RTSemEventDestroy failed! rc=%Rrc\n", rc));
            pThis->WriteEvent = NIL_RTSEMEVENT;

            RTCritSectLeave(&pThis->CritSect);
            rc = RTCritSectDelete(&pThis->CritSect);
            AssertMsgRC(rc, ("RTCritSectDelete failed! rc=%Rrc\n", rc));

#ifdef RTSEMRW_STRICT
            RTLockValidatorRecSharedDelete(&pThis->ValidatorRead);
            RTLockValidatorRecExclDelete(&pThis->ValidatorWrite);
#endif
            RTMemFree(pThis);
            rc = VINF_SUCCESS;
        }
        else
        {
            rc = VERR_SEM_BUSY;
            RTCritSectLeave(&pThis->CritSect);
        }
    }
    else
    {
        AssertMsgRC(rc, ("RTCritSectTryEnter failed! rc=%Rrc\n", rc));
        rc = VERR_SEM_BUSY;
    }

    return rc;
}
Пример #4
0
RTDECL(int) RTMemCacheCreate(PRTMEMCACHE phMemCache, size_t cbObject, size_t cbAlignment, uint32_t cMaxObjects,
                             PFNMEMCACHECTOR pfnCtor, PFNMEMCACHEDTOR pfnDtor, void *pvUser, uint32_t fFlags)

{
    AssertPtr(phMemCache);
    AssertPtrNull(pfnCtor);
    AssertPtrNull(pfnDtor);
    AssertReturn(!pfnDtor || pfnCtor, VERR_INVALID_PARAMETER);
    AssertReturn(cbObject > 0, VERR_INVALID_PARAMETER);
    AssertReturn(cbObject <= PAGE_SIZE / 8, VERR_INVALID_PARAMETER);
    AssertReturn(!fFlags, VERR_INVALID_PARAMETER);

    if (cbAlignment == 0)
    {
        if (cbObject <= 2)
            cbAlignment = cbObject;
        else if (cbObject <= 4)
            cbAlignment = 4;
        else if (cbObject <= 8)
            cbAlignment = 8;
        else if (cbObject <= 16)
            cbAlignment = 16;
        else if (cbObject <= 32)
            cbAlignment = 32;
        else
            cbAlignment = 64;
    }
    else
    {
        AssertReturn(!((cbAlignment - 1) & cbAlignment), VERR_NOT_POWER_OF_TWO);
        AssertReturn(cbAlignment <= 64, VERR_OUT_OF_RANGE);
    }

    /*
     * Allocate and initialize the instance memory.
     */
    RTMEMCACHEINT *pThis = (RTMEMCACHEINT *)RTMemAlloc(sizeof(*pThis));
    if (!pThis)
        return VERR_NO_MEMORY;
    int rc = RTCritSectInit(&pThis->CritSect);
    if (RT_FAILURE(rc))
    {
        RTMemFree(pThis);
        return rc;
    }

    pThis->u32Magic         = RTMEMCACHE_MAGIC;
    pThis->cbObject         = (uint32_t)RT_ALIGN_Z(cbObject, cbAlignment);
    pThis->cbAlignment      = (uint32_t)cbAlignment;
    pThis->cPerPage         = (uint32_t)((PAGE_SIZE - RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), cbAlignment)) / pThis->cbObject);
    while (  RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), 8)
           + pThis->cPerPage * pThis->cbObject
           + RT_ALIGN(pThis->cPerPage, 64) / 8 * 2
           > PAGE_SIZE)
        pThis->cPerPage--;
    pThis->cBits            = RT_ALIGN(pThis->cPerPage, 64);
    pThis->cMax             = cMaxObjects;
    pThis->fUseFreeList     = cbObject >= sizeof(RTMEMCACHEFREEOBJ)
                           && !pfnCtor
                           && !pfnDtor;
    pThis->pPageHead        = NULL;
    pThis->pfnCtor          = pfnCtor;
    pThis->pfnDtor          = pfnDtor;
    pThis->pvUser           = pvUser;
    pThis->cTotal           = 0;
    pThis->cFree            = 0;
    pThis->pPageHint        = NULL;
    pThis->pFreeTop         = NULL;

    /** @todo
     * Here is a puzzler (or maybe I'm just blind), the free list code breaks
     * badly on my macbook pro (i7) (32-bit).
     *
     * I tried changing the reads from unordered to ordered to no avail.  Then I
     * tried optimizing the code with the ASMAtomicCmpXchgExPtr function to
     * avoid some reads - no change. Inserting pause instructions did nothing
     * (as expected).  The only thing which seems to make a difference is
     * reading the pFreeTop pointer twice in the the free code... This is weird
     * or I'm overlooking something..
     *
     * No time to figure it out, so I'm disabling the broken code paths for
     * now. */
    pThis->fUseFreeList = false;

    *phMemCache = pThis;
    return VINF_SUCCESS;
}
static int vboxvfs_mount(struct mount *mp, struct thread *td)
{
    int rc;
    char *pszShare;
    int  cbShare, cbOption;
    int uid = 0, gid = 0;
    struct sf_glob_info *pShFlGlobalInfo;
    SHFLSTRING *pShFlShareName = NULL;
    int cbShFlShareName;

    printf("%s: Enter\n", __FUNCTION__);

    if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS))
        return EOPNOTSUPP;

    if (vfs_filteropt(mp->mnt_optnew, vboxvfs_opts))
    {
        vfs_mount_error(mp, "%s", "Invalid option");
        return EINVAL;
    }

    rc = vfs_getopt(mp->mnt_optnew, "from", (void **)&pszShare, &cbShare);
    if (rc || pszShare[cbShare-1] != '\0' || cbShare > 0xfffe)
        return EINVAL;

    rc = vfs_getopt(mp->mnt_optnew, "gid", (void **)&gid, &cbOption);
    if ((rc != ENOENT) && (rc || cbOption != sizeof(gid)))
        return EINVAL;

    rc = vfs_getopt(mp->mnt_optnew, "uid", (void **)&uid, &cbOption);
    if ((rc != ENOENT) && (rc || cbOption != sizeof(uid)))
        return EINVAL;

    pShFlGlobalInfo = RTMemAllocZ(sizeof(struct sf_glob_info));
    if (!pShFlGlobalInfo)
        return ENOMEM;

    cbShFlShareName = offsetof (SHFLSTRING, String.utf8) + cbShare + 1;
    pShFlShareName  = RTMemAllocZ(cbShFlShareName);
    if (!pShFlShareName)
        return VERR_NO_MEMORY;

    pShFlShareName->u16Length = cbShFlShareName;
    pShFlShareName->u16Size   = cbShFlShareName + 1;
    memcpy (pShFlShareName->String.utf8, pszShare, cbShare + 1);

    rc = vboxCallMapFolder (&g_vboxSFClient, pShFlShareName, &pShFlGlobalInfo->map);
    RTMemFree(pShFlShareName);

    if (RT_FAILURE (rc))
    {
        RTMemFree(pShFlGlobalInfo);
        printf("vboxCallMapFolder failed rc=%d\n", rc);
        return EPROTO;
    }

    pShFlGlobalInfo->uid = uid;
    pShFlGlobalInfo->gid = gid;

    mp->mnt_data = pShFlGlobalInfo;

    /* @todo root vnode. */

    vfs_getnewfsid(mp);
    vfs_mountedfrom(mp, pszShare);

    printf("%s: Leave rc=0\n", __FUNCTION__);

    return 0;
}
Пример #6
0
/**
 * Free a symbol structure previously allocated by a RTDbg method.
 *
 * @param   pSymInfo        The symbol info to free. NULL is ignored.
 */
RTDECL(void) RTDbgSymbolFree(PRTDBGSYMBOL pSymInfo)
{
    RTMemFree(pSymInfo);
}
/**
 * Free one USB device returned by getDevice().
 *
 * @param   pDevice     Pointer to the device.
 */
/*static*/ void
USBProxyService::freeDevice(PUSBDEVICE pDevice)
{
    freeDeviceMembers(pDevice);
    RTMemFree(pDevice);
}
Пример #8
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_FAILURE(RTR0MemUserCopyFrom(&Hdr, 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_FAILURE(RTR0MemUserCopyFrom(pHdr, 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.
     */
    rc = supdrvIOCtl(uCmd, &g_DevExt, pSession, pHdr, cbBuf);

    /*
     * 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_FAILURE(RTR0MemUserCopyTo(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;
}
Пример #9
0
void VBoxDispD3DGlobal2DFormatsTerm(PVBOXWDDMDISP_ADAPTER pAdapter)
{
    if (pAdapter->Formats.paFormstOps)
        RTMemFree((void *)pAdapter->Formats.paFormstOps);
}
RTDECL(int) RTCrStoreCertExportAsPem(RTCRSTORE hStore, uint32_t fFlags, const char *pszFilename)
{
    /*
     * Validate input.
     */
    AssertReturn(!fFlags, VERR_INVALID_FLAGS);

    /*
     * Start the enumeration first as this validates the store handle.
     */
    RTCRSTORECERTSEARCH Search;
    int rc = RTCrStoreCertFindAll(hStore, &Search);
    if (RT_SUCCESS(rc))
    {
        /*
         * Open the file for writing.
         *
         * Note! We must use text and no binary here, because the base-64 API
         *       below will use host specific EOL markers, not CRLF as PEM
         *       specifies.
         */
        PRTSTREAM hStrm;
        rc = RTStrmOpen(pszFilename, "w", &hStrm);
        if (RT_SUCCESS(rc))
        {
            /*
             * Enumerate the certificates in the store, writing them out one by one.
             */
            size_t          cbBase64  = 0;
            char           *pszBase64 = NULL;
            PCRTCRCERTCTX   pCertCtx;
            while ((pCertCtx = RTCrStoreCertSearchNext(hStore, &Search)) != NULL)
            {
                const char *pszMarker;
                switch (pCertCtx->fFlags & RTCRCERTCTX_F_ENC_MASK)
                {
                    case RTCRCERTCTX_F_ENC_X509_DER:    pszMarker = "CERTIFICATE";  break;
                    case RTCRCERTCTX_F_ENC_TAF_DER:     pszMarker = "TRUST ANCHOR"; break;
                    default:                            pszMarker = NULL;           break;
                }
                if (pszMarker && pCertCtx->cbEncoded > 0)
                {
                    /*
                     * Do the base64 conversion first.
                     */
                    size_t cchEncoded = RTBase64EncodedLength(pCertCtx->cbEncoded);
                    if (cchEncoded < cbBase64)
                    { /* likely */ }
                    else
                    {
                        size_t cbNew = RT_ALIGN(cchEncoded + 64, 128);
                        void *pvNew = RTMemRealloc(pszBase64, cbNew);
                        if (!pvNew)
                        {
                            rc = VERR_NO_MEMORY;
                            break;
                        }
                        cbBase64  = cbNew;
                        pszBase64 = (char *)pvNew;
                    }
                    rc = RTBase64Encode(pCertCtx->pabEncoded, pCertCtx->cbEncoded, pszBase64, cbBase64, &cchEncoded);
                    if (RT_FAILURE(rc))
                        break;

                    RTStrmPrintf(hStrm, "-----BEGIN %s-----\n", pszMarker);
                    RTStrmWrite(hStrm, pszBase64, cchEncoded);
                    rc = RTStrmPrintf(hStrm, "\n-----END %s-----\n", pszMarker);
                    if (RT_FAILURE(rc))
                        break;
                }

                RTCrCertCtxRelease(pCertCtx);
            }
            if (pCertCtx)
                RTCrCertCtxRelease(pCertCtx);
            RTMemFree(pszBase64);

            /*
             * Flush the output file before closing.
             */
            int rc2 = RTStrmFlush(hStrm);
            if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
                rc = rc2;
            RTStrmClearError(hStrm); /** @todo fix RTStrmClose... */
            rc2 = RTStrmClose(hStrm);
            if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
                rc = rc2;
        }

        int rc2 = RTCrStoreCertSearchDestroy(hStore, &Search); AssertRC(rc2);
    }
    return rc;
}
Пример #11
0
DECLCALLBACK(int) vboxUhgsmiD3DBufferCreate(PVBOXUHGSMI pHgsmi, uint32_t cbBuf,
        VBOXUHGSMI_SYNCHOBJECT_TYPE enmSynchType, HVBOXUHGSMI_SYNCHOBJECT hSynch,
        PVBOXUHGSMI_BUFFER* ppBuf)
{
    bool bSynchCreated = false;
    if (!cbBuf)
        return VERR_INVALID_PARAMETER;

    int rc = vboxUhgsmiBaseEventChkCreate(enmSynchType, &hSynch, &bSynchCreated);
    AssertRC(rc);
    if (RT_FAILURE(rc))
        return rc;

    cbBuf = VBOXWDDM_ROUNDBOUND(cbBuf, 0x1000);
    Assert(cbBuf);
    uint32_t cPages = cbBuf >> 12;
    Assert(cPages);

    PVBOXUHGSMI_PRIVATE_D3D pPrivate = VBOXUHGSMID3D_GET(pHgsmi);
    PVBOXUHGSMI_BUFFER_PRIVATE_D3D pBuf = (PVBOXUHGSMI_BUFFER_PRIVATE_D3D)RTMemAllocZ(RT_OFFSETOF(VBOXUHGSMI_BUFFER_PRIVATE_D3D, aLockPageIndices[cPages]));
    Assert(pBuf);
    if (pBuf)
    {
        struct
        {
            D3DDDICB_ALLOCATE DdiAlloc;
            D3DDDI_ALLOCATIONINFO DdiAllocInfo;
            VBOXWDDM_ALLOCINFO AllocInfo;
        } Buf;
        memset(&Buf, 0, sizeof (Buf));
        Buf.DdiAlloc.hResource = NULL;
        Buf.DdiAlloc.hKMResource = NULL;
        Buf.DdiAlloc.NumAllocations = 1;
        Buf.DdiAlloc.pAllocationInfo = &Buf.DdiAllocInfo;
        Buf.DdiAllocInfo.pPrivateDriverData = &Buf.AllocInfo;
        Buf.DdiAllocInfo.PrivateDriverDataSize = sizeof (Buf.AllocInfo);
        Buf.AllocInfo.enmType = VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER;
        Buf.AllocInfo.cbBuffer = cbBuf;
        Buf.AllocInfo.hSynch = hSynch;
        Buf.AllocInfo.enmSynchType = enmSynchType;

        HRESULT hr = pPrivate->pDevice->RtCallbacks.pfnAllocateCb(pPrivate->pDevice->hDevice, &Buf.DdiAlloc);
        Assert(hr == S_OK);
        if (hr == S_OK)
        {
            Assert(Buf.DdiAllocInfo.hAllocation);
            pBuf->BasePrivate.Base.pfnLock = vboxUhgsmiD3DBufferLock;
            pBuf->BasePrivate.Base.pfnUnlock = vboxUhgsmiD3DBufferUnlock;
//            pBuf->Base.pfnAdjustValidDataRange = vboxUhgsmiD3DBufferAdjustValidDataRange;
            pBuf->BasePrivate.Base.pfnDestroy = vboxUhgsmiD3DBufferDestroy;

            pBuf->BasePrivate.Base.hSynch = hSynch;
            pBuf->BasePrivate.Base.enmSynchType = enmSynchType;
            pBuf->BasePrivate.Base.cbBuffer = cbBuf;
            pBuf->BasePrivate.Base.bSynchCreated = bSynchCreated;

            pBuf->pDevice = pPrivate->pDevice;
            pBuf->BasePrivate.hAllocation = Buf.DdiAllocInfo.hAllocation;

            *ppBuf = &pBuf->BasePrivate.Base;

            return VINF_SUCCESS;
        }

        RTMemFree(pBuf);
    }
    else
        rc = VERR_NO_MEMORY;

    if (bSynchCreated)
        CloseHandle(hSynch);

    return rc;
}
Пример #12
0
/**
 * Worker for rtSemMutexSolRequest that handles the case where we go to sleep.
 *
 * @returns VINF_SUCCESS, VERR_INTERRUPTED, or VERR_SEM_DESTROYED.
 *          Returns without owning the mutex.
 * @param   pThis           The mutex instance.
 * @param   cMillies        The timeout, must be > 0 or RT_INDEFINITE_WAIT.
 * @param   fInterruptible  The wait type.
 *
 * @remarks This needs to be called with the mutex object held!
 */
static int rtSemMutexSolRequestSleep(PRTSEMMUTEXINTERNAL pThis, RTMSINTERVAL cMillies,
                                       bool fInterruptible)
{
    int rc = VERR_GENERAL_FAILURE;
    Assert(cMillies > 0);

    /*
     * Now we wait (sleep; although might spin and then sleep) & reference the mutex.
     */
    ASMAtomicIncU32(&pThis->cWaiters);
    ASMAtomicIncU32(&pThis->cRefs);

    if (cMillies != RT_INDEFINITE_WAIT)
    {
        clock_t cTicks   = drv_usectohz((clock_t)(cMillies * 1000L));
        clock_t cTimeout = ddi_get_lbolt();
        cTimeout        += cTicks;
        if (fInterruptible)
            rc = cv_timedwait_sig(&pThis->Cnd, &pThis->Mtx, cTimeout);
        else
            rc = cv_timedwait(&pThis->Cnd, &pThis->Mtx, cTimeout);
    }
    else
    {
        if (fInterruptible)
            rc = cv_wait_sig(&pThis->Cnd, &pThis->Mtx);
        else
        {
            cv_wait(&pThis->Cnd, &pThis->Mtx);
            rc = 1;
        }
    }

    ASMAtomicDecU32(&pThis->cWaiters);
    if (rc > 0)
    {
        if (pThis->u32Magic == RTSEMMUTEX_MAGIC)
        {
            if (pThis->hOwnerThread == NIL_RTNATIVETHREAD)
            {
                /*
                 * Woken up by a release from another thread.
                 */
                Assert(pThis->cRecursions == 0);
                pThis->cRecursions = 1;
                pThis->hOwnerThread = RTThreadNativeSelf();
                rc = VINF_SUCCESS;
            }
            else
            {
                /*
                 * Interrupted by some signal.
                 */
                rc = VERR_INTERRUPTED;
            }
        }
        else
        {
            /*
             * Awakened due to the destruction-in-progress broadcast.
             * We will cleanup if we're the last waiter.
             */
            rc = VERR_SEM_DESTROYED;
        }
    }
    else if (rc == -1)
    {
        /*
         * Timed out.
         */
        rc = VERR_TIMEOUT;
    }
    else
    {
        /*
         * Condition may not have been met, returned due to pending signal.
         */
        rc = VERR_INTERRUPTED;
    }

    if (!ASMAtomicDecU32(&pThis->cRefs))
    {
        Assert(RT_FAILURE_NP(rc));
        mutex_exit(&pThis->Mtx);
        cv_destroy(&pThis->Cnd);
        mutex_destroy(&pThis->Mtx);
        RTMemFree(pThis);
        return rc;
    }

    return rc;
}
Пример #13
0
static int tstVDBackendInfo(void)
{
    int rc;
#define MAX_BACKENDS 100
    VDBACKENDINFO aVDInfo[MAX_BACKENDS];
    unsigned cEntries;

#define CHECK(str) \
    do \
    { \
        RTPrintf("%s rc=%Rrc\n", str, rc); \
        if (RT_FAILURE(rc)) \
            return rc; \
    } while (0)

    rc = VDBackendInfo(MAX_BACKENDS, aVDInfo, &cEntries);
    CHECK("VDBackendInfo()");

    for (unsigned i=0; i < cEntries; i++)
    {
        RTPrintf("Backend %u: name=%s capabilities=%#06x extensions=",
                 i, aVDInfo[i].pszBackend, aVDInfo[i].uBackendCaps);
        if (aVDInfo[i].paFileExtensions)
        {
            PCVDFILEEXTENSION pa = aVDInfo[i].paFileExtensions;
            while (pa->pszExtension != NULL)
            {
                if (pa != aVDInfo[i].paFileExtensions)
                    RTPrintf(",");
                RTPrintf("%s (%s)", pa->pszExtension, tstVDDeviceType(pa->enmType));
                pa++;
            }
            if (pa == aVDInfo[i].paFileExtensions)
                RTPrintf("<EMPTY>");
        }
        else
            RTPrintf("<NONE>");
        RTPrintf(" config=");
        if (aVDInfo[i].paConfigInfo)
        {
            PCVDCONFIGINFO pa = aVDInfo[i].paConfigInfo;
            while (pa->pszKey != NULL)
            {
                if (pa != aVDInfo[i].paConfigInfo)
                    RTPrintf(",");
                RTPrintf("(key=%s type=", pa->pszKey);
                switch (pa->enmValueType)
                {
                    case VDCFGVALUETYPE_INTEGER:
                        RTPrintf("integer");
                        break;
                    case VDCFGVALUETYPE_STRING:
                        RTPrintf("string");
                        break;
                    case VDCFGVALUETYPE_BYTES:
                        RTPrintf("bytes");
                        break;
                    default:
                        RTPrintf("INVALID!");
                }
                RTPrintf(" default=");
                if (pa->pszDefaultValue)
                    RTPrintf("%s", pa->pszDefaultValue);
                else
                    RTPrintf("<NONE>");
                RTPrintf(" flags=");
                if (!pa->uKeyFlags)
                    RTPrintf("none");
                unsigned cFlags = 0;
                if (pa->uKeyFlags & VD_CFGKEY_MANDATORY)
                {
                    if (cFlags)
                        RTPrintf(",");
                    RTPrintf("mandatory");
                    cFlags++;
                }
                if (pa->uKeyFlags & VD_CFGKEY_EXPERT)
                {
                    if (cFlags)
                        RTPrintf(",");
                    RTPrintf("expert");
                    cFlags++;
                }
                RTPrintf(")");
                pa++;
            }
            if (pa == aVDInfo[i].paConfigInfo)
                RTPrintf("<EMPTY>");
        }
        else
            RTPrintf("<NONE>");
        RTPrintf("\n");

        PVDINTERFACE pVDIfs = NULL;
        VDINTERFACECONFIG ic;

        ic.pfnAreKeysValid = tstAreKeysValid;
        ic.pfnQuerySize    = tstQuerySize;
        ic.pfnQuery        = tstQuery;

        rc = VDInterfaceAdd(&ic.Core, "tstVD-2_Config", VDINTERFACETYPE_CONFIG,
                            NULL, sizeof(VDINTERFACECONFIG), &pVDIfs);
        AssertRC(rc);

        char *pszLocation, *pszName;
        rc = aVDInfo[i].pfnComposeLocation(pVDIfs, &pszLocation);
        CHECK("pfnComposeLocation()");
        if (pszLocation)
        {
            RTMemFree(pszLocation);
            if (aVDInfo[i].uBackendCaps & VD_CAP_FILE)
            {
                RTPrintf("Non-NULL location returned for file-based backend!\n");
                return VERR_INTERNAL_ERROR;
            }
        }
        rc = aVDInfo[i].pfnComposeName(pVDIfs, &pszName);
        CHECK("pfnComposeName()");
        if (pszName)
        {
            RTMemFree(pszName);
            if (aVDInfo[i].uBackendCaps & VD_CAP_FILE)
            {
                RTPrintf("Non-NULL name returned for file-based backend!\n");
                return VERR_INTERNAL_ERROR;
            }
        }
    }

#undef CHECK
    return 0;
}
Пример #14
0
int cpumR3DbGetCpuInfo(const char *pszName, PCPUMINFO pInfo)
{
    CPUMDBENTRY const *pEntry = NULL;
    int                rc;

    if (!strcmp(pszName, "host"))
    {
        /*
         * Create a CPU database entry for the host CPU.  This means getting
         * the CPUID bits from the real CPU and grabbing the closest matching
         * database entry for MSRs.
         */
        rc = CPUMR3CpuIdDetectUnknownLeafMethod(&pInfo->enmUnknownCpuIdMethod, &pInfo->DefCpuId);
        if (RT_FAILURE(rc))
            return rc;
        rc = CPUMR3CpuIdCollectLeaves(&pInfo->paCpuIdLeavesR3, &pInfo->cCpuIdLeaves);
        if (RT_FAILURE(rc))
            return rc;

        /* Lookup database entry for MSRs. */
        CPUMCPUVENDOR const enmVendor    = CPUMR3CpuIdDetectVendorEx(pInfo->paCpuIdLeavesR3[0].uEax,
                                                                     pInfo->paCpuIdLeavesR3[0].uEbx,
                                                                     pInfo->paCpuIdLeavesR3[0].uEcx,
                                                                     pInfo->paCpuIdLeavesR3[0].uEdx);
        uint32_t      const uStd1Eax     = pInfo->paCpuIdLeavesR3[1].uEax;
        uint8_t       const uFamily      = ASMGetCpuFamily(uStd1Eax);
        uint8_t       const uModel       = ASMGetCpuModel(uStd1Eax, enmVendor == CPUMCPUVENDOR_INTEL);
        uint8_t       const uStepping    = ASMGetCpuStepping(uStd1Eax);
        CPUMMICROARCH const enmMicroarch = CPUMR3CpuIdDetermineMicroarchEx(enmVendor, uFamily, uModel, uStepping);

        for (unsigned i = 0; i < RT_ELEMENTS(g_apCpumDbEntries); i++)
        {
            CPUMDBENTRY const *pCur = g_apCpumDbEntries[i];
            if ((CPUMCPUVENDOR)pCur->enmVendor == enmVendor)
            {
                /* Match against Family, Microarch, model and stepping.  Except
                   for family, always match the closer with preference given to
                   the later/older ones. */
                if (pCur->uFamily == uFamily)
                {
                    if (pCur->enmMicroarch == enmMicroarch)
                    {
                        if (pCur->uModel == uModel)
                        {
                            if (pCur->uStepping == uStepping)
                            {
                                /* Perfect match. */
                                pEntry = pCur;
                                break;
                            }

                            if (   !pEntry
                                || pEntry->uModel       != uModel
                                || pEntry->enmMicroarch != enmMicroarch
                                || pEntry->uFamily      != uFamily)
                                pEntry = pCur;
                            else if (  pCur->uStepping >= uStepping
                                     ? pCur->uStepping < pEntry->uStepping || pEntry->uStepping < uStepping
                                     : pCur->uStepping > pEntry->uStepping)
                                     pEntry = pCur;
                        }
                        else if (   !pEntry
                                 || pEntry->enmMicroarch != enmMicroarch
                                 || pEntry->uFamily      != uFamily)
                            pEntry = pCur;
                        else if (  pCur->uModel >= uModel
                                 ? pCur->uModel < pEntry->uModel || pEntry->uModel < uModel
                                 : pCur->uModel > pEntry->uModel)
                            pEntry = pCur;
                    }
                    else if (   !pEntry
                             || pEntry->uFamily != uFamily)
                        pEntry = pCur;
                    else if (  pCur->enmMicroarch >= enmMicroarch
                             ? pCur->enmMicroarch < pEntry->enmMicroarch || pEntry->enmMicroarch < enmMicroarch
                             : pCur->enmMicroarch > pEntry->enmMicroarch)
                        pEntry = pCur;
                }
                /* We don't do closeness matching on family, we use the first
                   entry for the CPU vendor instead. (P4 workaround.) */
                else if (!pEntry)
                    pEntry = pCur;
            }
        }

        if (pEntry)
            LogRel(("CPUM: Matched host CPU %s %#x/%#x/%#x %s with CPU DB entry '%s' (%s %#x/%#x/%#x %s).\n",
                    CPUMR3CpuVendorName(enmVendor), uFamily, uModel, uStepping, CPUMR3MicroarchName(enmMicroarch),
                    pEntry->pszName,  CPUMR3CpuVendorName((CPUMCPUVENDOR)pEntry->enmVendor), pEntry->uFamily, pEntry->uModel,
                    pEntry->uStepping, CPUMR3MicroarchName(pEntry->enmMicroarch) ));
        else
        {
            pEntry = g_apCpumDbEntries[0];
            LogRel(("CPUM: No matching processor database entry %s %#x/%#x/%#x %s, falling back on '%s'.\n",
                    CPUMR3CpuVendorName(enmVendor), uFamily, uModel, uStepping, CPUMR3MicroarchName(enmMicroarch),
                    pEntry->pszName));
        }
    }
    else
    {
        /*
         * We're supposed to be emulating a specific CPU that is included in
         * our CPU database.  The CPUID tables needs to be copied onto the
         * heap so the caller can modify them and so they can be freed like
         * in the host case above.
         */
        for (unsigned i = 0; i < RT_ELEMENTS(g_apCpumDbEntries); i++)
            if (!strcmp(pszName, g_apCpumDbEntries[i]->pszName))
            {
                pEntry = g_apCpumDbEntries[i];
                break;
            }
        if (!pEntry)
        {
            LogRel(("CPUM: Cannot locate any CPU by the name '%s'\n", pszName));
            return VERR_CPUM_DB_CPU_NOT_FOUND;
        }

        pInfo->cCpuIdLeaves = pEntry->cCpuIdLeaves;
        if (pEntry->cCpuIdLeaves)
        {
            pInfo->paCpuIdLeavesR3 = (PCPUMCPUIDLEAF)RTMemDup(pEntry->paCpuIdLeaves,
                                                              sizeof(pEntry->paCpuIdLeaves[0]) * pEntry->cCpuIdLeaves);
            if (!pInfo->paCpuIdLeavesR3)
                return VERR_NO_MEMORY;
        }
        else
            pInfo->paCpuIdLeavesR3 = NULL;

        pInfo->enmUnknownCpuIdMethod = pEntry->enmUnknownCpuId;
        pInfo->DefCpuId         = pEntry->DefUnknownCpuId;

        LogRel(("CPUM: Using CPU DB entry '%s' (%s %#x/%#x/%#x %s).\n",
                pEntry->pszName, CPUMR3CpuVendorName((CPUMCPUVENDOR)pEntry->enmVendor),
                pEntry->uFamily, pEntry->uModel, pEntry->uStepping, CPUMR3MicroarchName(pEntry->enmMicroarch) ));
    }

    pInfo->fMsrMask             = pEntry->fMsrMask;
    pInfo->iFirstExtCpuIdLeaf   = 0; /* Set by caller. */
    pInfo->uPadding             = 0;
    pInfo->uScalableBusFreq     = pEntry->uScalableBusFreq;
    pInfo->paCpuIdLeavesR0      = NIL_RTR0PTR;
    pInfo->paMsrRangesR0        = NIL_RTR0PTR;
    pInfo->paCpuIdLeavesRC      = NIL_RTRCPTR;
    pInfo->paMsrRangesRC        = NIL_RTRCPTR;

    /*
     * Copy the MSR range.
     */
    uint32_t        cMsrs   = 0;
    PCPUMMSRRANGE   paMsrs  = NULL;

    PCCPUMMSRRANGE  pCurMsr = pEntry->paMsrRanges;
    uint32_t        cLeft   = pEntry->cMsrRanges;
    while (cLeft-- > 0)
    {
        rc = cpumR3MsrRangesInsert(&paMsrs, &cMsrs, pCurMsr);
        if (RT_FAILURE(rc))
        {
            Assert(!paMsrs); /* The above function frees this. */
            RTMemFree(pInfo->paCpuIdLeavesR3);
            pInfo->paCpuIdLeavesR3 = NULL;
            return rc;
        }
        pCurMsr++;
    }

    pInfo->paMsrRangesR3   = paMsrs;
    pInfo->cMsrRanges      = cMsrs;
    return VINF_SUCCESS;
}
Пример #15
0
static DECLCALLBACK(int) scriptRun(PVM pVM, RTFILE File)
{
    RTPrintf("info: running script...\n");
    uint64_t cb;
    int rc = RTFileGetSize(File, &cb);
    if (RT_SUCCESS(rc))
    {
        if (cb == 0)
            return VINF_SUCCESS;
        if (cb < _1M)
        {
            char *pszBuf = (char *)RTMemAllocZ(cb + 1);
            if (pszBuf)
            {
                rc = RTFileRead(File, pszBuf, cb, NULL);
                if (RT_SUCCESS(rc))
                {
                    pszBuf[cb] = '\0';

                    /*
                     * Now process what's in the buffer.
                     */
                    char *psz = pszBuf;
                    while (psz && *psz)
                    {
                        /* skip blanks. */
                        while (RT_C_IS_SPACE(*psz))
                            psz++;
                        if (!*psz)
                            break;

                        /* end of line */
                        char *pszNext;
                        char *pszEnd = strchr(psz, '\n');
                        if (!pszEnd)
                            pszEnd = strchr(psz, '\r');
                        if (!pszEnd)
                            pszNext = pszEnd = strchr(psz, '\0');
                        else
                            pszNext = pszEnd + 1;

                        if (*psz != ';' && *psz != '#' && *psz != '/')
                        {
                            /* strip end */
                            *pszEnd = '\0';
                            while (pszEnd > psz && RT_C_IS_SPACE(pszEnd[-1]))
                                *--pszEnd = '\0';

                            /* process the line */
                            RTPrintf("debug: executing script line '%s'\n",  psz);
                            rc = scriptCommand(pVM, psz, pszEnd - psz);
                            if (RT_FAILURE(rc))
                            {
                                RTPrintf("error: '%s' failed: %Rrc\n", psz, rc);
                                break;
                            }
                        }
                        /* else comment line */

                        /* next */
                        psz = pszNext;
                    }

                }
                else
                    RTPrintf("error: failed to read script file: %Rrc\n", rc);
                RTMemFree(pszBuf);
            }
            else
            {
                RTPrintf("error: Out of memory. (%d bytes)\n", cb + 1);
                rc = VERR_NO_MEMORY;
            }
        }
        else
            RTPrintf("error: script file is too large (0x%llx bytes)\n", cb);
    }
    else
        RTPrintf("error: couldn't get size of script file: %Rrc\n", rc);

    return rc;
}
Пример #16
0
VBOXDDU_DECL(int) VDDbgIoLogEventGetStartDiscard(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
                                                 PRTRANGE *ppaRanges, unsigned *pcRanges)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

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

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

    if (   pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START
        && pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_DISCARD)
    {
        IoLogEntryStart Entry;
        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
        if (RT_SUCCESS(rc))
        {
            PRTRANGE paRanges = NULL;
            IoLogEntryDiscard DiscardRange;

            pIoLogger->offReadNext += sizeof(Entry);
            *pfAsync   = RT_BOOL(Entry.u8AsyncIo);
            *pidEvent  = RT_LE2H_U64(Entry.u64Id);
            *pcRanges  = RT_LE2H_U32(Entry.Discard.cRanges);

            paRanges = (PRTRANGE)RTMemAllocZ(*pcRanges * sizeof(RTRANGE));
            if (paRanges)
            {
                for (unsigned i = 0; i < *pcRanges; i++)
                {
                    rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + i*sizeof(DiscardRange),
                                      &DiscardRange, sizeof(DiscardRange), NULL);
                    if (RT_FAILURE(rc))
                        break;

                    paRanges[i].offStart = RT_LE2H_U64(DiscardRange.u64Off);
                    paRanges[i].cbRange  = RT_LE2H_U32(DiscardRange.u32Discard);
                }

                if (RT_SUCCESS(rc))
                {
                    pIoLogger->offReadNext += *pcRanges * sizeof(DiscardRange);
                    *ppaRanges = paRanges;
                }
                else
                {
                    pIoLogger->offReadNext -= sizeof(Entry);
                    RTMemFree(paRanges);
                }
            }
            else
                rc = VERR_NO_MEMORY;
        }
    }
    else
        rc = VERR_INVALID_STATE;

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

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;

}
Пример #17
0
/**
 * Free a line number structure previously allocated by a RTDbg method.
 *
 * @param   pLine           The line number to free. NULL is ignored.
 */
RTDECL(void) RTDbgLineFree(PRTDBGLINE pLine)
{
    RTMemFree(pLine);
}
Пример #18
0
static DECLCALLBACK(void) hgsmiEnvFree(void *pvEnv, void *pv)
{
    NOREF(pvEnv);
    RTMemFree(pv);
}
Пример #19
0
/**
 * Convert guest absolute VFS path (starting from VFS root) to a host path
 * within mounted shared folder (returning it as a char *).
 *
 * @param mp            Mount data structure
 * @param pszGuestPath  Guest absolute VFS path (starting from VFS root)
 * @param cbGuestPath   Size of pszGuestPath
 * @param pszHostPath   Returned char * wich contains host path
 * @param cbHostPath    Returned pszHostPath size
 *
 * @return 0 on success, error code otherwise
 */
int
vboxvfs_guest_path_to_char_path_internal(mount_t mp, char *pszGuestPath, int cbGuestPath, char **pszHostPath, int *cbHostPath)
{
    vboxvfs_mount_t *pMount;

    /* Guest side: mount point path buffer and its size */
    char       *pszMntPointPath;
    int         cbMntPointPath = MAXPATHLEN;

    /* Host side: path within mounted shared folder and its size */
    char       *pszHostPathInternal;
    size_t      cbHostPathInternal;

    int rc;

    AssertReturn(mp, EINVAL);
    AssertReturn(pszGuestPath, EINVAL); AssertReturn(cbGuestPath >= 0, EINVAL);
    AssertReturn(pszHostPath,  EINVAL); AssertReturn(cbHostPath,       EINVAL);

    pMount = (vboxvfs_mount_t *)vfs_fsprivate(mp); AssertReturn(pMount, EINVAL); AssertReturn(pMount->pRootVnode, EINVAL);

    /* Get mount point path */
    pszMntPointPath = (char *)RTMemAllocZ(cbMntPointPath);
    if (pszMntPointPath)
    {
        rc = vn_getpath(pMount->pRootVnode, pszMntPointPath, &cbMntPointPath);
        if (rc == 0 && cbGuestPath >= cbMntPointPath)
        {
            cbHostPathInternal  = cbGuestPath - cbMntPointPath + 1;
            pszHostPathInternal = (char *)RTMemAllocZ(cbHostPathInternal);
            if (pszHostPathInternal)
            {
                memcpy(pszHostPathInternal, pszGuestPath + cbMntPointPath, cbGuestPath - cbMntPointPath);
                PDEBUG("guest<->host path converion result: '%s' mounted to '%s'", pszHostPathInternal, pszMntPointPath);

                RTMemFree(pszMntPointPath);

                *pszHostPath = pszHostPathInternal;
                *cbHostPath  = cbGuestPath - cbMntPointPath;

                return 0;

            }
            else
            {
                PDEBUG("No memory to allocate buffer for guest<->host path conversion (cbHostPathInternal)");
                rc = ENOMEM;
            }

        }
        else
        {
            PDEBUG("Unable to get guest vnode path: %d", rc);
        }

        RTMemFree(pszMntPointPath);
    }
    else
    {
        PDEBUG("No memory to allocate buffer for guest<->host path conversion (pszMntPointPath)");
        rc = ENOMEM;
    }

    return rc;
}
Пример #20
0
RTDECL(int) RTMpNotificationRegister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser)
{
    PRTMPNOTIFYREG  pCur;
    PRTMPNOTIFYREG  pNew;

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

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

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

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

    RTSpinlockAcquire(g_hRTMpNotifySpinLock);

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

    ASMAtomicIncU32(&g_iRTMpGeneration);

    RTSpinlockRelease(g_hRTMpNotifySpinLock);

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

    return VINF_SUCCESS;
}
Пример #21
0
void freeSavedDisplayScreenshot(uint8_t *pu8Data)
{
    /* @todo not necessary when caching is implemented. */
    RTMemFree(pu8Data);
}
Пример #22
0
/** @copydoc VBOXHDDBACKEND::pfnCreate */
static int rawCreate(const char *pszFilename, uint64_t cbSize,
                     unsigned uImageFlags, const char *pszComment,
                     PCVDGEOMETRY pPCHSGeometry, PCVDGEOMETRY pLCHSGeometry,
                     PCRTUUID pUuid, unsigned uOpenFlags,
                     unsigned uPercentStart, unsigned uPercentSpan,
                     PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
                     PVDINTERFACE pVDIfsOperation, VDTYPE enmType,
                     void **ppBackendData)
{
    LogFlowFunc(("pszFilename=\"%s\" cbSize=%llu uImageFlags=%#x pszComment=\"%s\" pPCHSGeometry=%#p pLCHSGeometry=%#p Uuid=%RTuuid uOpenFlags=%#x uPercentStart=%u uPercentSpan=%u pVDIfsDisk=%#p pVDIfsImage=%#p pVDIfsOperation=%#p enmType=%u ppBackendData=%#p",
                 pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, enmType, ppBackendData));
    int rc;
    PRAWIMAGE pImage;

    PFNVDPROGRESS pfnProgress = NULL;
    void *pvUser = NULL;
    PVDINTERFACEPROGRESS pIfProgress = VDIfProgressGet(pVDIfsOperation);
    if (pIfProgress)
    {
        pfnProgress = pIfProgress->pfnProgress;
        pvUser = pIfProgress->Core.pvUser;
    }

    /* Check the VD container type. Yes, hard disk must be allowed, otherwise
     * various tools using this backend for hard disk images will fail. */
    if (enmType != VDTYPE_HDD && enmType != VDTYPE_DVD && enmType != VDTYPE_FLOPPY)
    {
        rc = VERR_VD_INVALID_TYPE;
        goto out;
    }

    /* Check open flags. All valid flags are supported. */
    if (uOpenFlags & ~VD_OPEN_FLAGS_MASK)
    {
        rc = VERR_INVALID_PARAMETER;
        goto out;
    }

    /* Check remaining arguments. */
    if (   !VALID_PTR(pszFilename)
        || !*pszFilename
        || !VALID_PTR(pPCHSGeometry)
        || !VALID_PTR(pLCHSGeometry))
    {
        rc = VERR_INVALID_PARAMETER;
        goto out;
    }

    pImage = (PRAWIMAGE)RTMemAllocZ(sizeof(RAWIMAGE));
    if (!pImage)
    {
        rc = VERR_NO_MEMORY;
        goto out;
    }
    pImage->pszFilename = pszFilename;
    pImage->pStorage = NULL;
    pImage->pVDIfsDisk = pVDIfsDisk;
    pImage->pVDIfsImage = pVDIfsImage;

    rc = rawCreateImage(pImage, cbSize, uImageFlags, pszComment,
                        pPCHSGeometry, pLCHSGeometry, uOpenFlags,
                        pfnProgress, pvUser, uPercentStart, uPercentSpan);
    if (RT_SUCCESS(rc))
    {
        /* So far the image is opened in read/write mode. Make sure the
         * image is opened in read-only mode if the caller requested that. */
        if (uOpenFlags & VD_OPEN_FLAGS_READONLY)
        {
            rawFreeImage(pImage, false);
            rc = rawOpenImage(pImage, uOpenFlags);
            if (RT_FAILURE(rc))
            {
                RTMemFree(pImage);
                goto out;
            }
        }
        *ppBackendData = pImage;
    }
    else
        RTMemFree(pImage);

out:
    LogFlowFunc(("returns %Rrc (pBackendData=%#p)\n", rc, *ppBackendData));
    return rc;
}
Пример #23
0
RTDECL(uint32_t) RTThreadCtxHooksRelease(RTTHREADCTX hThreadCtx)
{
    PRTTHREADCTXINT pThis = hThreadCtx;
    if (pThis == NIL_RTTHREADCTX)
        return 0;

    RTTHREADCTX_VALID_RETURN_RC(hThreadCtx, UINT32_MAX);
    Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD));

    pThis->fRegistered = false;
    uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);

    if (   pThis->hOwner == RTThreadNativeSelf()
        && cRefs == 1)
    {
        /*
         * removectx() will invoke rtThreadCtxHooksSolFree() and there is no way to bypass it and still use
         * rtThreadCtxHooksSolFree() at the same time.  Hence the convulated reference counting.
         *
         * When this function is called from the owner thread and is the last reference, we call removectx() which
         * will invoke rtThreadCtxHooksSolFree() with cRefs = 1 and that will then free the hook object.
         *
         * When the function is called from a different thread, we simply decrement the reference. Whenever the
         * ring-0 thread dies, Solaris will call rtThreadCtxHooksSolFree() which will free the hook object.
         */
        int rc;
        if (g_frtSolOldThreadCtx)
        {
            rc = g_rtSolThreadCtx.Remove.pfnSol_removectx_old(curthread,
                                                              pThis,
                                                              rtThreadCtxHooksSolPreempting,
                                                              rtThreadCtxHooksSolResumed,
                                                              NULL,                          /* fork */
                                                              NULL,                          /* lwp_create */
                                                              rtThreadCtxHooksSolFree);
        }
        else
        {
            rc = g_rtSolThreadCtx.Remove.pfnSol_removectx(curthread,
                                                          pThis,
                                                          rtThreadCtxHooksSolPreempting,
                                                          rtThreadCtxHooksSolResumed,
                                                          NULL,                              /* fork */
                                                          NULL,                              /* lwp_create */
                                                          NULL,                              /* exit */
                                                          rtThreadCtxHooksSolFree);
        }
        AssertMsg(rc, ("removectx failed. rc=%d\n", rc));
        NOREF(rc);

#ifdef VBOX_STRICT
        cRefs = ASMAtomicReadU32(&pThis->cRefs);
        Assert(!cRefs);
#endif
        cRefs = 0;
    }
    else if (!cRefs)
    {
        /*
         * The ring-0 thread for this hook object has already died. Free up the object as we have no more references.
         */
        Assert(pThis->hOwner != RTThreadNativeSelf());
        ASMAtomicWriteU32(&pThis->u32Magic, ~RTTHREADCTXINT_MAGIC);
        RTMemFree(pThis);
    }

    return cRefs;
}
Пример #24
0
/**
 * Releases a reference to the event semaphore.
 *
 * @param   pThis       The event semaphore.
 */
DECLINLINE(void) rtR0SemEventLnxRelease(PRTSEMEVENTINTERNAL pThis)
{
    if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0))
        RTMemFree(pThis);
}
/**
 * Destroy the given kernel module information record.
 *
 * @returns nothing.
 * @param   pThis            The record to destroy.
 */
static void rtKrnlModInfoDestroy(PRTKRNLMODINFOINT pThis)
{
    RTMemFree(pThis);
}
Пример #26
0
int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list)
{
    int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (sock < 0)
    {
        Log(("NetIfList: socket() -> %d\n", errno));
        return NULL;
    }
    struct ifaddrs *IfAddrs, *pAddr;
    int rc = getifaddrs(&IfAddrs);
    if (rc)
    {
        close(sock);
        Log(("NetIfList: getifaddrs() -> %d\n", rc));
        return VERR_INTERNAL_ERROR;
    }

    PDARWINETHERNIC pEtherNICs = DarwinGetEthernetControllers();
    while (pEtherNICs)
    {
        size_t cbNameLen = strlen(pEtherNICs->szName) + 1;
        PNETIFINFO pNew = (PNETIFINFO)RTMemAllocZ(RT_OFFSETOF(NETIFINFO, szName[cbNameLen]));
        pNew->MACAddress = pEtherNICs->Mac;
        pNew->enmMediumType = NETIF_T_ETHERNET;
        pNew->Uuid = pEtherNICs->Uuid;
        Assert(sizeof(pNew->szShortName) > sizeof(pEtherNICs->szBSDName));
        memcpy(pNew->szShortName, pEtherNICs->szBSDName, sizeof(pEtherNICs->szBSDName));
        pNew->szShortName[sizeof(pEtherNICs->szBSDName)] = '\0';
        memcpy(pNew->szName, pEtherNICs->szName, cbNameLen);

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

        for (pAddr = IfAddrs; pAddr != NULL; pAddr = pAddr->ifa_next)
        {
            if (strcmp(pNew->szShortName, pAddr->ifa_name))
                continue;

            struct sockaddr_in *pIPAddr, *pIPNetMask;
            struct sockaddr_in6 *pIPv6Addr, *pIPv6NetMask;

            switch (pAddr->ifa_addr->sa_family)
            {
                case AF_INET:
                    if (pNew->IPAddress.u)
                        break;
                    pIPAddr = (struct sockaddr_in *)pAddr->ifa_addr;
                    Assert(sizeof(pNew->IPAddress) == sizeof(pIPAddr->sin_addr));
                    pNew->IPAddress.u = pIPAddr->sin_addr.s_addr;
                    pIPNetMask = (struct sockaddr_in *)pAddr->ifa_netmask;
                    Assert(pIPNetMask->sin_family == AF_INET);
                    Assert(sizeof(pNew->IPNetMask) == sizeof(pIPNetMask->sin_addr));
                    pNew->IPNetMask.u = pIPNetMask->sin_addr.s_addr;
                    break;
                case AF_INET6:
                    if (pNew->IPv6Address.s.Lo || pNew->IPv6Address.s.Hi)
                        break;
                    pIPv6Addr = (struct sockaddr_in6 *)pAddr->ifa_addr;
                    Assert(sizeof(pNew->IPv6Address) == sizeof(pIPv6Addr->sin6_addr));
                    memcpy(pNew->IPv6Address.au8,
                           pIPv6Addr->sin6_addr.__u6_addr.__u6_addr8,
                           sizeof(pNew->IPv6Address));
                    pIPv6NetMask = (struct sockaddr_in6 *)pAddr->ifa_netmask;
                    Assert(pIPv6NetMask->sin6_family == AF_INET6);
                    Assert(sizeof(pNew->IPv6NetMask) == sizeof(pIPv6NetMask->sin6_addr));
                    memcpy(pNew->IPv6NetMask.au8,
                           pIPv6NetMask->sin6_addr.__u6_addr.__u6_addr8,
                           sizeof(pNew->IPv6NetMask));
                    break;
            }
        }

        ComObjPtr<HostNetworkInterface> IfObj;
        IfObj.createObject();
        if (SUCCEEDED(IfObj->init(Bstr(pEtherNICs->szName), HostNetworkInterfaceType_Bridged, pNew)))
            list.push_back(IfObj);
        RTMemFree(pNew);

        /* next, free current */
        void *pvFree = pEtherNICs;
        pEtherNICs = pEtherNICs->pNext;
        RTMemFree(pvFree);
    }

    freeifaddrs(IfAddrs);
    close(sock);
    return VINF_SUCCESS;
}
Пример #27
0
RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles,
                                   PFNRTPROGRESS pfnProgressCallback, void *pvUser)
{
    /* Validate input */
    AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
    AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
    AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER);

    RTFILE file;
    int rc = RTFileOpen(&file, pszManifestFile, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_ALL);
    if (RT_FAILURE(rc))
        return rc;

    PRTMANIFESTTEST paFiles = 0;
    void *pvBuf = 0;
    do
    {
        paFiles = (PRTMANIFESTTEST)RTMemAllocZ(sizeof(RTMANIFESTTEST) * cFiles);
        if (!paFiles)
        {
            rc = VERR_NO_MEMORY;
            break;
        }

        RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 };
        for (size_t i = 0; i < cFiles; ++i)
        {
            paFiles[i].pszTestFile = papszFiles[i];
            /* Calculate the SHA1 digest of every file */
            if (pfnProgressCallback)
            {
                callback.cCurrentFile = i;
                rc = RTSha1DigestFromFile(paFiles[i].pszTestFile, (char**)&paFiles[i].pszTestDigest, rtSHAProgressCallback, &callback);
            }
            else
                rc = RTSha1DigestFromFile(paFiles[i].pszTestFile, (char**)&paFiles[i].pszTestDigest, NULL, NULL);
            if (RT_FAILURE(rc))
                break;
        }

        if (RT_SUCCESS(rc))
        {
            size_t cbSize = 0;
            rc = RTManifestWriteFilesBuf(&pvBuf, &cbSize, paFiles, cFiles);
            if (RT_FAILURE(rc))
                break;

            rc = RTFileWrite(file, pvBuf, cbSize, 0);
        }
    }while (0);

    RTFileClose(file);

    /* Cleanup */
    if (pvBuf)
        RTMemFree(pvBuf);
    for (size_t i = 0; i < cFiles; ++i)
        if (paFiles[i].pszTestDigest)
            RTStrFree((char*)paFiles[i].pszTestDigest);
    RTMemFree(paFiles);

    /* Delete the manifest file on failure */
    if (RT_FAILURE(rc))
        RTFileDelete(pszManifestFile);

    return rc;
}
Пример #28
0
int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list)
{
    int rc = VINF_SUCCESS;
    size_t cbNeeded;
    char *pBuf, *pNext;
    int aiMib[6];
    unsigned short u16DefaultIface = 0; /* shut up gcc. */
    bool fDefaultIfaceExistent = true;

    /* Get the index of the interface associated with default route. */
    rc = getDefaultIfaceIndex(&u16DefaultIface, PF_INET);
    if (RT_FAILURE(rc))
    {
        fDefaultIfaceExistent = false;
        rc = VINF_SUCCESS;
    }

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

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

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

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

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

        size_t cbNameLen = pSdl->sdl_nlen + 1;
        PNETIFINFO pNew = (PNETIFINFO)RTMemAllocZ(RT_OFFSETOF(NETIFINFO, szName[cbNameLen]));
        if (!pNew)
        {
            rc = VERR_NO_MEMORY;
            break;
        }
        memcpy(pNew->MACAddress.au8, LLADDR(pSdl), sizeof(pNew->MACAddress.au8));
        pNew->enmMediumType = NETIF_T_ETHERNET;
        Assert(sizeof(pNew->szShortName) >= cbNameLen);
        strlcpy(pNew->szShortName, pSdl->sdl_data, cbNameLen);
        strlcpy(pNew->szName, pSdl->sdl_data, cbNameLen);
        /* Generate UUID from name and MAC address. */
        RTUUID uuid;
        RTUuidClear(&uuid);
        memcpy(&uuid, pNew->szShortName, RT_MIN(cbNameLen, sizeof(uuid)));
        uuid.Gen.u8ClockSeqHiAndReserved = (uuid.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80;
        uuid.Gen.u16TimeHiAndVersion = (uuid.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000;
        memcpy(uuid.Gen.au8Node, pNew->MACAddress.au8, sizeof(uuid.Gen.au8Node));
        pNew->Uuid = uuid;

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

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

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

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

            ComObjPtr<HostNetworkInterface> IfObj;
            IfObj.createObject();
            if (SUCCEEDED(IfObj->init(Bstr(pNew->szName), enmType, pNew)))
            {
                /* Make sure the default interface gets to the beginning. */
                if (   fDefaultIfaceExistent
                    && pIfMsg->ifm_index == u16DefaultIface)
                    list.push_front(IfObj);
                else
                    list.push_back(IfObj);
            }
        }
        RTMemFree(pNew);
    }

    close(sock);
    free(pBuf);
    return rc;


}
Пример #29
0
RTDECL(int) RTSemRWCreateEx(PRTSEMRW phRWSem, uint32_t fFlags,
                            RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...)
{
    AssertReturn(!(fFlags & ~RTSEMRW_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);

    /*
     * Allocate memory.
     */
    int rc;
    struct RTSEMRWINTERNAL *pThis = (struct RTSEMRWINTERNAL *)RTMemAlloc(sizeof(struct RTSEMRWINTERNAL));
    if (pThis)
    {
        /*
         * Create the semaphores.
         */
        rc = RTSemEventCreateEx(&pThis->WriteEvent, RTSEMEVENT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, NULL);
        if (RT_SUCCESS(rc))
        {
            rc = RTSemEventMultiCreateEx(&pThis->ReadEvent, RTSEMEVENT_FLAGS_NO_LOCK_VAL, NIL_RTLOCKVALCLASS, NULL);
            if (RT_SUCCESS(rc))
            {
                rc = RTCritSectInitEx(&pThis->CritSect, RTCRITSECT_FLAGS_NO_LOCK_VAL,
                                      NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_NONE, NULL);
                if (RT_SUCCESS(rc))
                {
                    /*
                     * Signal the read semaphore and initialize other variables.
                     */
                    rc = RTSemEventMultiSignal(pThis->ReadEvent);
                    if (RT_SUCCESS(rc))
                    {
                        pThis->u32Padding           = UINT32_C(0xa5a55a5a);
                        pThis->cReads               = 0;
                        pThis->cWrites              = 0;
                        pThis->cWriterReads         = 0;
                        pThis->cWritesWaiting       = 0;
                        pThis->hWriter              = NIL_RTNATIVETHREAD;
                        pThis->fNeedResetReadEvent  = true;
                        pThis->u32Magic             = RTSEMRW_MAGIC;
#ifdef RTSEMRW_STRICT
                        bool const fLVEnabled = !(fFlags & RTSEMRW_FLAGS_NO_LOCK_VAL);
                        if (!pszNameFmt)
                        {
                            static uint32_t volatile s_iSemRWAnon = 0;
                            uint32_t i = ASMAtomicIncU32(&s_iSemRWAnon) - 1;
                            RTLockValidatorRecExclInit(&pThis->ValidatorWrite, hClass, uSubClass, pThis,
                                                       fLVEnabled, "RTSemRW-%u", i);
                            RTLockValidatorRecSharedInit(&pThis->ValidatorRead, hClass, uSubClass, pThis,
                                                         false /*fSignaller*/, fLVEnabled, "RTSemRW-%u", i);
                        }
                        else
                        {
                            va_list va;
                            va_start(va, pszNameFmt);
                            RTLockValidatorRecExclInitV(&pThis->ValidatorWrite, hClass, uSubClass, pThis,
                                                        fLVEnabled, pszNameFmt, va);
                            va_end(va);
                            va_start(va, pszNameFmt);
                            RTLockValidatorRecSharedInitV(&pThis->ValidatorRead, hClass, uSubClass, pThis,
                                                          false /*fSignaller*/, fLVEnabled, pszNameFmt, va);
                            va_end(va);
                        }
                        RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core);
#endif
                        *phRWSem = pThis;
                        return VINF_SUCCESS;
                    }
                    RTCritSectDelete(&pThis->CritSect);
                }
                RTSemEventMultiDestroy(pThis->ReadEvent);
            }
            RTSemEventDestroy(pThis->WriteEvent);
        }
        RTMemFree(pThis);
    }
    else
        rc = VERR_NO_MEMORY;

    return rc;
}
Пример #30
0
/**
 * Parse the arguments.
 *
 * @returns 0 on success, fully bitched exit code on failure.
 *
 * @param   argc    Argument count.
 * @param   argv    Argument vector.
 *
 * @todo r=bird: The --help and --version options shall not return a
 *               non-zero exit code.  So, this method need to grow some
 *               complexity.  I'm to blame for that blunder :/
 */
int VBoxNetBaseService::parseArgs(int argc, char **argv)
{

    RTGETOPTSTATE State;
    PRTGETOPTDEF paOptionArray = getOptionsPtr();
    int rc = RTGetOptInit(&State, argc, argv, paOptionArray, m->m_vecOptionDefs.size(), 0, 0 /*fFlags*/);
    AssertRCReturn(rc, 49);
#if 0
    /* default initialization */
    m_enmTrunkType = kIntNetTrunkType_WhateverNone;
#endif
    Log2(("BaseService: parseArgs enter\n"));

    for (;;)
    {
        RTGETOPTUNION Val;
        rc = RTGetOpt(&State, &Val);
        if (!rc)
            break;
        switch (rc)
        {
            case 'N': // --name
                m->m_ServiceName = Val.psz;
                break;

            case 'n': // --network
                m->m_NetworkName = Val.psz;
                break;

            case 't': //--trunk-name
                m->m_TrunkName = Val.psz;
                break;

            case 'T': //--trunk-type
                if (!strcmp(Val.psz, "none"))
                    m->m_enmTrunkType = kIntNetTrunkType_None;
                else if (!strcmp(Val.psz, "whatever"))
                    m->m_enmTrunkType = kIntNetTrunkType_WhateverNone;
                else if (!strcmp(Val.psz, "netflt"))
                    m->m_enmTrunkType = kIntNetTrunkType_NetFlt;
                else if (!strcmp(Val.psz, "netadp"))
                    m->m_enmTrunkType = kIntNetTrunkType_NetAdp;
                else if (!strcmp(Val.psz, "srvnat"))
                    m->m_enmTrunkType = kIntNetTrunkType_SrvNat;
                else
                {
                    RTStrmPrintf(g_pStdErr, "Invalid trunk type '%s'\n", Val.psz);
                    return RTEXITCODE_SYNTAX;
                }
                break;

            case 'a': // --mac-address
                m->m_MacAddress = Val.MacAddr;
                break;

            case 'i': // --ip-address
                m->m_Ipv4Address = Val.IPv4Addr;
                break;

            case 'm': // --netmask
                m->m_Ipv4Netmask = Val.IPv4Addr;
                break;

            case 'v': // --verbose
                m->m_cVerbosity++;
                break;

            case 'V': // --version (missed)
                RTPrintf("%sr%u\n", RTBldCfgVersion(), RTBldCfgRevision());
                return 1; /** @todo this exit code is wrong, of course. :/ */

            case 'M': // --need-main
                m->m_fNeedMain = true;
                break;

            case 'h': // --help (missed)
                RTPrintf("%s Version %sr%u\n"
                         "(C) 2009-" VBOX_C_YEAR " " VBOX_VENDOR "\n"
                         "All rights reserved.\n"
                         "\n"
                         "Usage: %s <options>\n"
                         "\n"
                         "Options:\n",
                         RTProcShortName(),
                         RTBldCfgVersion(),
                         RTBldCfgRevision(),
                         RTProcShortName());
                for (unsigned int i = 0; i < m->m_vecOptionDefs.size(); i++)
                    RTPrintf("    -%c, %s\n", m->m_vecOptionDefs[i]->iShort, m->m_vecOptionDefs[i]->pszLong);
                usage(); /* to print Service Specific usage */
                return 1; /** @todo this exit code is wrong, of course. :/ */

            default:
            {
                int rc1 = parseOpt(rc, Val);
                if (RT_FAILURE(rc1))
                {
                    RTEXITCODE rcExit = RTGetOptPrintError(rc, &Val);
                    RTPrintf("Use --help for more information.\n");
                    return rcExit;
                }
                break;
            }
        }
    }

    RTMemFree(paOptionArray);
    return RTEXITCODE_SUCCESS;
}