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; }
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; }
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; }
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; }
/** * 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); }
/** * 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; }
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; }
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; }
/** * 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; }
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; }
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; }
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; }
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; }
/** * 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); }
static DECLCALLBACK(void) hgsmiEnvFree(void *pvEnv, void *pv) { NOREF(pvEnv); RTMemFree(pv); }
/** * 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; }
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; }
void freeSavedDisplayScreenshot(uint8_t *pu8Data) { /* @todo not necessary when caching is implemented. */ RTMemFree(pu8Data); }
/** @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; }
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; }
/** * 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); }
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; }
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; }
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; }
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; }
/** * 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; }