/** * Internal. Free all allocated space for representing an image except pImage, * and optionally delete the image from disk. */ static int rawFreeImage(PRAWIMAGE pImage, bool fDelete) { int rc = VINF_SUCCESS; /* Freeing a never allocated image (e.g. because the open failed) is * not signalled as an error. After all nothing bad happens. */ if (pImage) { if (pImage->pStorage) { /* No point updating the file that is deleted anyway. */ if (!fDelete) { /* For newly created images in sequential mode fill it to * the nominal size. */ if ( pImage->uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) && pImage->fCreate) { /* Fill rest of image with zeroes, a must for sequential * images to reach the nominal size. */ uint64_t uOff; void *pvBuf = RTMemTmpAllocZ(RAW_FILL_SIZE); if (!pvBuf) goto out; uOff = pImage->offAccess; /* Write data to all image blocks. */ while (uOff < pImage->cbSize) { unsigned cbChunk = (unsigned)RT_MIN(pImage->cbSize - uOff, RAW_FILL_SIZE); rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, uOff, pvBuf, cbChunk); if (RT_FAILURE(rc)) goto out; uOff += cbChunk; } out: if (pvBuf) RTMemTmpFree(pvBuf); } rawFlushImage(pImage); } rc = vdIfIoIntFileClose(pImage->pIfIo, pImage->pStorage); pImage->pStorage = NULL; } if (fDelete && pImage->pszFilename) vdIfIoIntFileDelete(pImage->pIfIo, pImage->pszFilename); } LogFlowFunc(("returns %Rrc\n", rc)); return rc; }
/** * Adds an entry for a file with the specified set of attributes. * * @returns IPRT status code. * * @param hManifest The manifest handle. * @param hVfsIos The I/O stream handle of the entry. This will * be processed to its end on successful return. * (Must be positioned at the start to get * the expected results.) * @param pszEntry The entry name. * @param fAttrs The attributes to create for this stream. */ RTDECL(int) RTManifestEntryAddIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry, uint32_t fAttrs) { /* * Note! This is a convenicence function, so just use the available public * methods to get the job done. */ AssertReturn(fAttrs < RTMANIFEST_ATTR_END, VERR_INVALID_PARAMETER); AssertPtr(pszEntry); /* * Allocate and initialize the hash contexts, hash digests and I/O buffer. */ PRTMANIFESTHASHES pHashes = rtManifestHashesCreate(fAttrs); if (!pHashes) return VERR_NO_TMP_MEMORY; int rc; size_t cbBuf = _1M; void *pvBuf = RTMemTmpAlloc(cbBuf); if (RT_UNLIKELY(!pvBuf)) { cbBuf = _4K; pvBuf = RTMemTmpAlloc(cbBuf); } if (RT_LIKELY(pvBuf)) { /* * Process the stream data. */ for (;;) { size_t cbRead; rc = RTVfsIoStrmRead(hVfsIos, pvBuf, cbBuf, true /*fBlocking*/, &cbRead); if ( (rc == VINF_EOF && cbRead == 0) || RT_FAILURE(rc)) break; rtManifestHashesUpdate(pHashes, pvBuf, cbRead); } RTMemTmpFree(pvBuf); if (RT_SUCCESS(rc)) { /* * Add the entry with the finalized hashes. */ rtManifestHashesFinal(pHashes); rc = RTManifestEntryAdd(hManifest, pszEntry); if (RT_SUCCESS(rc)) rc = rtManifestHashesSetAttrs(pHashes, hManifest, pszEntry); } } else { rtManifestHashesDestroy(pHashes); rc = VERR_NO_TMP_MEMORY; } return rc; }
static void tst1(size_t cTest, size_t cchDigits, char chSep) { RTTestISubF("tst #%u (digits: %u; sep: %c)", cTest, cchDigits, chSep ? chSep : ' '); /* We try to create max possible + one. */ size_t cTimes = 1; for (size_t i = 0; i < cchDigits; ++i) cTimes *= 10; /* Allocate the result array. */ char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *)); RTTESTI_CHECK_RETV(papszNames != NULL); int rc = VERR_INTERNAL_ERROR; /* The test loop. */ size_t i; for (i = 0; i < cTimes; i++) { char szName[RTPATH_MAX]; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS); if (RT_FAILURE(rc)) break; RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VINF_SUCCESS); if (RT_FAILURE(rc)) { RTTestIFailed("RTDirCreateUniqueNumbered(%s) call #%u -> %Rrc\n", szName, i, rc); break; } RTTESTI_CHECK(papszNames[i] = RTStrDup(szName)); if (!papszNames[i]) break; RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]); } /* Try to create one more, which shouldn't be possible. */ if (RT_SUCCESS(rc)) { char szName[RTPATH_MAX]; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), "RTDirCreateUniqueNumbered"), VINF_SUCCESS); if (RT_SUCCESS(rc)) RTTESTI_CHECK_RC(rc = RTDirCreateUniqueNumbered(szName, sizeof(szName), 0700, cchDigits, chSep), VERR_ALREADY_EXISTS); } /* cleanup */ while (i-- > 0) { RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); RTStrFree(papszNames[i]); } RTMemTmpFree(papszNames); }
RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed, PFNRTPROGRESS pfnProgressCallback, void *pvUser) { /* Validate input */ AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER); AssertPtrReturn(papszFiles, VERR_INVALID_POINTER); AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_POINTER); int rc = VINF_SUCCESS; /* Create our compare list */ PRTMANIFESTTEST paFiles = (PRTMANIFESTTEST)RTMemTmpAllocZ(sizeof(RTMANIFESTTEST) * cFiles); if (!paFiles) return VERR_NO_MEMORY; RTMANIFESTCALLBACKDATA callback = { pfnProgressCallback, pvUser, cFiles, 0 }; /* Fill our compare list */ for (size_t i = 0; i < cFiles; ++i) { char *pszDigest; if (pfnProgressCallback) { callback.cCurrentFile = i; rc = RTSha1DigestFromFile(papszFiles[i], &pszDigest, rtSHAProgressCallback, &callback); } else rc = RTSha1DigestFromFile(papszFiles[i], &pszDigest, NULL, NULL); if (RT_FAILURE(rc)) break; paFiles[i].pszTestFile = (char*)papszFiles[i]; paFiles[i].pszTestDigest = pszDigest; } /* Do the verification */ if (RT_SUCCESS(rc)) rc = RTManifestVerify(pszManifestFile, paFiles, cFiles, piFailed); /* Cleanup */ for (size_t i = 0; i < cFiles; ++i) { if (paFiles[i].pszTestDigest) RTStrFree((char*)paFiles[i].pszTestDigest); } RTMemTmpFree(paFiles); return rc; }
static void tstDirCreateTemp(const char *pszSubTest, const char *pszTemplate, unsigned cTimes, bool fSkipXCheck) { RTTestISub(pszSubTest); /* Allocate the result array. */ char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *)); RTTESTI_CHECK_RETV(papszNames != NULL); /* The test loop. */ unsigned i; for (i = 0; i < cTimes; i++) { int rc; char szName[RTPATH_MAX]; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), pszTemplate), VINF_SUCCESS); if (RT_FAILURE(rc)) break; RTTESTI_CHECK(papszNames[i] = RTStrDup(szName)); if (!papszNames[i]) break; rc = RTDirCreateTemp(papszNames[i]); if (rc != VINF_SUCCESS) { RTTestIFailed("RTDirCreateTemp(%s) call #%u -> %Rrc\n", szName, i, rc); RTStrFree(papszNames[i]); papszNames[i] = NULL; break; } RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]); RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("szName %s\nReturned %s\n", szName, papszNames[i])); if (!fSkipXCheck) RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, ("szName %s\nReturned %s\n", szName, papszNames[i])); } /* cleanup */ while (i-- > 0) { RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); RTStrFree(papszNames[i]); } RTMemTmpFree(papszNames); }
/** * Output processing task, handles outgoing frames */ static void vboxNetFltFreeBSDoutput(void *arg, int pending) { PVBOXNETFLTINS pThis = (PVBOXNETFLTINS)arg; struct mbuf *m, *m0; struct ifnet *ifp = pThis->u.s.ifp; unsigned int cSegs = 0; bool fDropIt = false, fActive; PINTNETSG pSG; VBOXCURVNET_SET(ifp->if_vnet); vboxNetFltRetain(pThis, true /* fBusy */); for (;;) { mtx_lock_spin(&pThis->u.s.outq.ifq_mtx); _IF_DEQUEUE(&pThis->u.s.outq, m); mtx_unlock_spin(&pThis->u.s.outq.ifq_mtx); if (m == NULL) break; for (m0 = m; m0 != NULL; m0 = m0->m_next) if (m0->m_len > 0) cSegs++; #ifdef PADD_RUNT_FRAMES_FROM_HOST if (m_length(m, NULL) < 60) cSegs++; #endif /* Create a copy and deliver to the virtual switch */ pSG = RTMemTmpAlloc(RT_OFFSETOF(INTNETSG, aSegs[cSegs])); vboxNetFltFreeBSDMBufToSG(pThis, m, pSG, cSegs, 0); fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, NULL /* pvIf */, pSG, INTNETTRUNKDIR_HOST); RTMemTmpFree(pSG); if (fDropIt) m_freem(m); else ether_output_frame(ifp, m); } vboxNetFltRelease(pThis, true /* fBusy */); VBOXCURVNET_RESTORE(); }
/** * Frees allocated pages, for bailing out on failure. * * This will not call VMSetError on failure but will use AssertLogRel instead. * * @param pVM The cross context VM structure. * @param pAllocReq The allocation request to undo. */ GMMR3DECL(void) GMMR3FreeAllocatedPages(PVM pVM, GMMALLOCATEPAGESREQ const *pAllocReq) { uint32_t cb = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[pAllocReq->cPages]); PGMMFREEPAGESREQ pReq = (PGMMFREEPAGESREQ)RTMemTmpAllocZ(cb); AssertLogRelReturnVoid(pReq); pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; pReq->Hdr.cbReq = cb; pReq->enmAccount = pAllocReq->enmAccount; pReq->cPages = pAllocReq->cPages; uint32_t iPage = pAllocReq->cPages; while (iPage-- > 0) { Assert(pAllocReq->aPages[iPage].idPage != NIL_GMM_PAGEID); pReq->aPages[iPage].idPage = pAllocReq->aPages[iPage].idPage; } int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_PAGES, 0, &pReq->Hdr); AssertLogRelRC(rc); RTMemTmpFree(pReq); }
/** * Gets an entry. * * @returns IPRT status code. * @param pThis The manifest to work with. * @param pszEntry The entry name. * @param fNeedNormalization Whether rtManifestValidateNameEntry said it * needed normalization. * @param cchEntry The length of the name. * @param ppEntry Where to return the entry pointer on success. */ static int rtManifestGetEntry(RTMANIFESTINT *pThis, const char *pszEntry, bool fNeedNormalization, size_t cchEntry, PRTMANIFESTENTRY *ppEntry) { PRTMANIFESTENTRY pEntry; AssertCompileMemberOffset(RTMANIFESTATTR, StrCore, 0); if (!fNeedNormalization) pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszEntry); else { char *pszCopy = (char *)RTMemTmpAlloc(cchEntry + 1); if (RT_UNLIKELY(!pszCopy)) return VERR_NO_TMP_MEMORY; memcpy(pszCopy, pszEntry, cchEntry + 1); rtManifestNormalizeEntry(pszCopy); pEntry = (PRTMANIFESTENTRY)RTStrSpaceGet(&pThis->Entries, pszCopy); RTMemTmpFree(pszCopy); } *ppEntry = pEntry; return pEntry ? VINF_SUCCESS : VERR_NOT_FOUND; }
RTDECL(int) RTEnvSetUtf8(const char *pszVar, const char *pszValue) { AssertReturn(strchr(pszVar, '=') == NULL, VERR_ENV_INVALID_VAR_NAME); size_t cwcVar; int rc = RTStrCalcUtf16LenEx(pszVar, RTSTR_MAX, &cwcVar); if (RT_SUCCESS(rc)) { size_t cwcValue; rc = RTStrCalcUtf16LenEx(pszVar, RTSTR_MAX, &cwcValue); if (RT_SUCCESS(rc)) { PRTUTF16 pwszTmp = (PRTUTF16)RTMemTmpAlloc((cwcVar + 1 + cwcValue + 1) * sizeof(RTUTF16)); if (pwszTmp) { rc = RTStrToUtf16Ex(pszVar, RTSTR_MAX, &pwszTmp, cwcVar + 1, NULL); if (RT_SUCCESS(rc)) { PRTUTF16 pwszTmpValue = &pwszTmp[cwcVar]; *pwszTmpValue++ = '='; rc = RTStrToUtf16Ex(pszValue, RTSTR_MAX, &pwszTmpValue, cwcValue + 1, NULL); if (RT_SUCCESS(rc)) { if (!_wputenv(pwszTmp)) rc = VINF_SUCCESS; else rc = RTErrConvertFromErrno(errno); } } RTMemTmpFree(pwszTmp); } else rc = VERR_NO_TMP_MEMORY; } } return rc; }
/** * Check the credentials and return the gid/uid of user. * * @param pszUser username * @param pszPasswd password * @param gid where to store the GID of the user * @param uid where to store the UID of the user * @returns IPRT status code */ static int rtCheckCredentials(const char *pszUser, const char *pszPasswd, gid_t *pGid, uid_t *pUid) { #if defined(RT_OS_LINUX) struct passwd *pw; pw = getpwnam(pszUser); if (!pw) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd *spwd; /* works only if /etc/shadow is accessible */ spwd = getspnam(pszUser); if (spwd) pw->pw_passwd = spwd->sp_pwdp; /* Default fCorrect=true if no password specified. In that case, pw->pw_passwd * must be NULL (no password set for this user). Fail if a password is specified * but the user does not have one assigned. */ int fCorrect = !pszPasswd || !*pszPasswd; if (pw->pw_passwd && *pw->pw_passwd) { struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data)); /* be reentrant */ char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data); fCorrect = pszEncPasswd && !strcmp(pszEncPasswd, pw->pw_passwd); RTMemTmpFree(data); } if (!fCorrect) return VERR_AUTHENTICATION_FAILURE; *pGid = pw->pw_gid; *pUid = pw->pw_uid; return VINF_SUCCESS; #elif defined(RT_OS_SOLARIS) struct passwd *ppw, pw; char szBuf[1024]; if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) return VERR_AUTHENTICATION_FAILURE; if (!pszPasswd) pszPasswd = ""; struct spwd spwd; char szPwdBuf[1024]; /* works only if /etc/shadow is accessible */ if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL) ppw->pw_passwd = spwd.sp_pwdp; char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); if (strcmp(pszEncPasswd, ppw->pw_passwd)) return VERR_AUTHENTICATION_FAILURE; *pGid = ppw->pw_gid; *pUid = ppw->pw_uid; return VINF_SUCCESS; #else NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); return VERR_AUTHENTICATION_FAILURE; #endif }
/** * VMMR3Init worker that initiates the switcher code (aka core code). * * This is core per VM code which might need fixups and/or for ease of use are * put on linear contiguous backing. * * @returns VBox status code. * @param pVM Pointer to the VM. */ int vmmR3SwitcherInit(PVM pVM) { #ifndef VBOX_WITH_RAW_MODE return VINF_SUCCESS; #else /* * Calc the size. */ unsigned cbCoreCode = 0; for (unsigned iSwitcher = 0; iSwitcher < RT_ELEMENTS(s_apSwitchers); iSwitcher++) { pVM->vmm.s.aoffSwitchers[iSwitcher] = cbCoreCode; PVMMSWITCHERDEF pSwitcher = s_apSwitchers[iSwitcher]; if (pSwitcher) { AssertRelease((unsigned)pSwitcher->enmType == iSwitcher); cbCoreCode += RT_ALIGN_32(pSwitcher->cbCode + 1, 32); } } /* * Allocate contiguous pages for switchers and deal with * conflicts in the intermediate mapping of the code. */ pVM->vmm.s.cbCoreCode = RT_ALIGN_32(cbCoreCode, PAGE_SIZE); pVM->vmm.s.pvCoreCodeR3 = SUPR3ContAlloc(pVM->vmm.s.cbCoreCode >> PAGE_SHIFT, &pVM->vmm.s.pvCoreCodeR0, &pVM->vmm.s.HCPhysCoreCode); int rc = VERR_NO_MEMORY; if (pVM->vmm.s.pvCoreCodeR3) { rc = PGMR3MapIntermediate(pVM, pVM->vmm.s.pvCoreCodeR0, pVM->vmm.s.HCPhysCoreCode, cbCoreCode); if (rc == VERR_PGM_INTERMEDIATE_PAGING_CONFLICT) { /* try more allocations - Solaris, Linux. */ const unsigned cTries = 8234; struct VMMInitBadTry { RTR0PTR pvR0; void *pvR3; RTHCPHYS HCPhys; RTUINT cb; } *paBadTries = (struct VMMInitBadTry *)RTMemTmpAlloc(sizeof(*paBadTries) * cTries); AssertReturn(paBadTries, VERR_NO_TMP_MEMORY); unsigned i = 0; do { paBadTries[i].pvR3 = pVM->vmm.s.pvCoreCodeR3; paBadTries[i].pvR0 = pVM->vmm.s.pvCoreCodeR0; paBadTries[i].HCPhys = pVM->vmm.s.HCPhysCoreCode; i++; pVM->vmm.s.pvCoreCodeR0 = NIL_RTR0PTR; pVM->vmm.s.HCPhysCoreCode = NIL_RTHCPHYS; pVM->vmm.s.pvCoreCodeR3 = SUPR3ContAlloc(pVM->vmm.s.cbCoreCode >> PAGE_SHIFT, &pVM->vmm.s.pvCoreCodeR0, &pVM->vmm.s.HCPhysCoreCode); if (!pVM->vmm.s.pvCoreCodeR3) break; rc = PGMR3MapIntermediate(pVM, pVM->vmm.s.pvCoreCodeR0, pVM->vmm.s.HCPhysCoreCode, cbCoreCode); } while ( rc == VERR_PGM_INTERMEDIATE_PAGING_CONFLICT && i < cTries - 1); /* cleanup */ if (RT_FAILURE(rc)) { paBadTries[i].pvR3 = pVM->vmm.s.pvCoreCodeR3; paBadTries[i].pvR0 = pVM->vmm.s.pvCoreCodeR0; paBadTries[i].HCPhys = pVM->vmm.s.HCPhysCoreCode; paBadTries[i].cb = pVM->vmm.s.cbCoreCode; i++; LogRel(("Failed to allocated and map core code: rc=%Rrc\n", rc)); } while (i-- > 0) { LogRel(("Core code alloc attempt #%d: pvR3=%p pvR0=%p HCPhys=%RHp\n", i, paBadTries[i].pvR3, paBadTries[i].pvR0, paBadTries[i].HCPhys)); SUPR3ContFree(paBadTries[i].pvR3, paBadTries[i].cb >> PAGE_SHIFT); } RTMemTmpFree(paBadTries); } }
/** * Destroys the hashes. * * @param pHashes The hashes structure. NULL is ignored. */ static void rtManifestHashesDestroy(PRTMANIFESTHASHES pHashes) { RTMemTmpFree(pHashes); }
/** * Reads the extension pack descriptor. * * @returns NULL on success, pointer to an error message on failure (caller * deletes it). * @param a_pszDir The directory containing the description file. * @param a_pExtPackDesc Where to store the extension pack descriptor. * @param a_pObjInfo Where to store the object info for the file (unix * attribs). Optional. */ RTCString *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo) { vboxExtPackClearDesc(a_pExtPackDesc); /* * Query the object info. */ RTFSOBJINFO ObjInfo; int rc = RTVfsFileQueryInfo(hVfsFile, &ObjInfo, RTFSOBJATTRADD_UNIX); if (RT_FAILURE(rc)) return &(new RTCString)->printf("RTVfsFileQueryInfo failed: %Rrc", rc); if (a_pObjInfo) *a_pObjInfo = ObjInfo; /* * The simple approach, read the whole thing into memory and pass this to * the XML parser. */ /* Check the file size. */ if (ObjInfo.cbObject > _1M || ObjInfo.cbObject < 0) return &(new RTCString)->printf("The XML file is too large (%'RU64 bytes)", ObjInfo.cbObject); size_t const cbFile = (size_t)ObjInfo.cbObject; /* Rewind to the start of the file. */ rc = RTVfsFileSeek(hVfsFile, 0, RTFILE_SEEK_BEGIN, NULL); if (RT_FAILURE(rc)) return &(new RTCString)->printf("RTVfsFileSeek(,0,BEGIN) failed: %Rrc", rc); /* Allocate memory and read the file content into it. */ void *pvFile = RTMemTmpAlloc(cbFile); if (!pvFile) return &(new RTCString)->printf("RTMemTmpAlloc(%zu) failed", cbFile); RTCString *pstrErr = NULL; rc = RTVfsFileRead(hVfsFile, pvFile, cbFile, NULL); if (RT_FAILURE(rc)) pstrErr = &(new RTCString)->printf("RTVfsFileRead failed: %Rrc", rc); /* * Parse the file. */ xml::Document Doc; if (RT_SUCCESS(rc)) { xml::XmlMemParser Parser; RTCString strFileName = VBOX_EXTPACK_DESCRIPTION_NAME; try { Parser.read(pvFile, cbFile, strFileName, Doc); } catch (xml::XmlError Err) { pstrErr = new RTCString(Err.what()); rc = VERR_PARSE_ERROR; } } RTMemTmpFree(pvFile); /* * Hand the xml doc over to the common code. */ if (RT_SUCCESS(rc)) pstrErr = vboxExtPackLoadDescFromDoc(&Doc, a_pExtPackDesc); return pstrErr; }
static int VBoxUSBMonSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal) { LogFunc((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl Dev=%d Cmd=%d pArg=%p Mode=%d\n", Dev, Cmd, pArg)); /* * Get the session from the soft state item. */ vboxusbmon_state_t *pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, getminor(Dev)); if (!pState) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: no state data for %d\n", getminor(Dev))); return EINVAL; } /* * Read the request wrapper. Though We don't really need wrapper struct. now * it's room for the future as Solaris isn't generous regarding the size. */ VBOXUSBREQ ReqWrap; if (IOCPARM_LEN(Cmd) != sizeof(ReqWrap)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap))); return ENOTTY; } int rc = ddi_copyin((void *)pArg, &ReqWrap, sizeof(ReqWrap), Mode); if (RT_UNLIKELY(rc)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d.\n", pArg, Cmd, rc)); return EINVAL; } if (ReqWrap.u32Magic != VBOXUSBMON_MAGIC) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad magic %#x; pArg=%p Cmd=%d.\n", ReqWrap.u32Magic, pArg, Cmd)); return EINVAL; } if (RT_UNLIKELY( ReqWrap.cbData == 0 || ReqWrap.cbData > _1M*16)) { LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad size %#x; pArg=%p Cmd=%d.\n", ReqWrap.cbData, pArg, Cmd)); return EINVAL; } /* * Read the request. */ void *pvBuf = RTMemTmpAlloc(ReqWrap.cbData); if (RT_UNLIKELY(!pvBuf)) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData)); return ENOMEM; } rc = ddi_copyin((void *)(uintptr_t)ReqWrap.pvDataR3, pvBuf, ReqWrap.cbData, Mode); if (RT_UNLIKELY(rc)) { RTMemTmpFree(pvBuf); LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc)); return EFAULT; } if (RT_UNLIKELY( ReqWrap.cbData != 0 && !VALID_PTR(pvBuf))) { RTMemTmpFree(pvBuf); LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: pvBuf invalid pointer %p\n", pvBuf)); return EINVAL; } Log((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: pid=%d.\n", (int)RTProcSelf())); /* * Process the IOCtl. */ size_t cbDataReturned; rc = vboxUSBMonSolarisProcessIOCtl(Cmd, pState, pvBuf, ReqWrap.cbData, &cbDataReturned); ReqWrap.rc = rc; rc = 0; if (RT_UNLIKELY(cbDataReturned > ReqWrap.cbData)) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData)); cbDataReturned = ReqWrap.cbData; } ReqWrap.cbData = cbDataReturned; /* * Copy the request back to user space. */ rc = ddi_copyout(&ReqWrap, (void *)pArg, sizeof(ReqWrap), Mode); if (RT_LIKELY(!rc)) { /* * Copy the payload (if any) back to user space. */ if (cbDataReturned > 0) { rc = ddi_copyout(pvBuf, (void *)(uintptr_t)ReqWrap.pvDataR3, cbDataReturned, Mode); if (RT_UNLIKELY(rc)) { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyout failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc)); rc = EFAULT; } } } else { LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyout(1) failed pArg=%p Cmd=%d\n", pArg, Cmd)); rc = EFAULT; } *pVal = rc; RTMemTmpFree(pvBuf); return rc; }
/** * Cleans up a GMMR0FreePages request. * @param pReq Pointer to the request (returned by GMMR3FreePagesPrepare). */ GMMR3DECL(void) GMMR3FreePagesCleanup(PGMMFREEPAGESREQ pReq) { RTMemTmpFree(pReq); }
/** * Internal: Create a raw image. */ static int rawCreateImage(PRAWIMAGE pImage, uint64_t cbSize, unsigned uImageFlags, const char *pszComment, PCVDGEOMETRY pPCHSGeometry, PCVDGEOMETRY pLCHSGeometry, unsigned uOpenFlags, PFNVDPROGRESS pfnProgress, void *pvUser, unsigned uPercentStart, unsigned uPercentSpan) { int rc; RTFOFF cbFree = 0; uint64_t uOff; void *pvBuf = NULL; int32_t fOpen; uImageFlags |= VD_IMAGE_FLAGS_FIXED; pImage->uOpenFlags = uOpenFlags & ~VD_OPEN_FLAGS_READONLY; pImage->uImageFlags = uImageFlags; pImage->fCreate = true; pImage->PCHSGeometry = *pPCHSGeometry; pImage->LCHSGeometry = *pLCHSGeometry; pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk); pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage); AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER); if (uImageFlags & VD_IMAGE_FLAGS_DIFF) { rc = vdIfError(pImage->pIfError, VERR_VD_RAW_INVALID_TYPE, RT_SRC_POS, N_("Raw: cannot create diff image '%s'"), pImage->pszFilename); goto out; } /* Create image file. */ fOpen = VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, true /* fCreate */); if (uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL) fOpen &= ~RTFILE_O_READ; rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename, fOpen, &pImage->pStorage); if (RT_FAILURE(rc)) { rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Raw: cannot create image '%s'"), pImage->pszFilename); goto out; } if (!(uOpenFlags & VD_OPEN_FLAGS_SEQUENTIAL)) { /* Check the free space on the disk and leave early if there is not * sufficient space available. */ rc = vdIfIoIntFileGetFreeSpace(pImage->pIfIo, pImage->pszFilename, &cbFree); if (RT_SUCCESS(rc) /* ignore errors */ && ((uint64_t)cbFree < cbSize)) { rc = vdIfError(pImage->pIfError, VERR_DISK_FULL, RT_SRC_POS, N_("Raw: disk would overflow creating image '%s'"), pImage->pszFilename); goto out; } /* Allocate & commit whole file if fixed image, it must be more * effective than expanding file by write operations. */ rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, cbSize); if (RT_FAILURE(rc)) { rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Raw: setting image size failed for '%s'"), pImage->pszFilename); goto out; } /* Fill image with zeroes. We do this for every fixed-size image since * on some systems (for example Windows Vista), it takes ages to write * a block near the end of a sparse file and the guest could complain * about an ATA timeout. */ pvBuf = RTMemTmpAllocZ(RAW_FILL_SIZE); if (!pvBuf) { rc = VERR_NO_MEMORY; goto out; } uOff = 0; /* Write data to all image blocks. */ while (uOff < cbSize) { unsigned cbChunk = (unsigned)RT_MIN(cbSize, RAW_FILL_SIZE); rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, uOff, pvBuf, cbChunk, NULL); if (RT_FAILURE(rc)) { rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Raw: writing block failed for '%s'"), pImage->pszFilename); goto out; } uOff += cbChunk; if (pfnProgress) { rc = pfnProgress(pvUser, uPercentStart + uOff * uPercentSpan * 98 / (cbSize * 100)); if (RT_FAILURE(rc)) goto out; } } } if (RT_SUCCESS(rc) && pfnProgress) pfnProgress(pvUser, uPercentStart + uPercentSpan * 98 / 100); pImage->cbSize = cbSize; rc = rawFlushImage(pImage); out: if (pvBuf) RTMemTmpFree(pvBuf); if (RT_SUCCESS(rc) && pfnProgress) pfnProgress(pvUser, uPercentStart + uPercentSpan); if (RT_FAILURE(rc)) rawFreeImage(pImage, rc != VERR_ALREADY_EXISTS); return rc; }
/** * Parses any string and tests if it is an IPv6 Address * * This function should NOT be used directly. If you do, note * that no security checks are done at the moment. This can change. * * @returns iprt sstatus code. * @param pszAddress The strin that holds the IPv6 address * @param addressLength The length of pszAddress * @param pszAddressOut Returns a plain, full blown IPv6 address * as a char array * @param addressOutSize The size of pszAddressOut (length) * @param pPortOut 32 bit unsigned integer, holding the port * If pszAddress doesn't contain a port, it's 0 * @param pszScopeOut Returns the scope of the address, if none it's 0 * @param scopeOutSize sizeof(pszScopeOut) * @param pBrackets returns true if the address was enclosed in brackets * @param pEmbeddedV4 returns true if the address is an embedded IPv4 address * @param followRfc if set to true, the function follows RFC (default) */ static int rtStrParseAddrStr6(const char *pszAddress, size_t addressLength, char *pszAddressOut, size_t addressOutSize, uint32_t *pPortOut, char *pszIfIdOut, size_t ifIdOutSize, bool *pBrackets, bool *pEmbeddedV4, bool followRfc) { /************************\ * Pointer Hell Ahead * \************************/ const char szIpV6AddressChars[] = "ABCDEF01234567890abcdef.:[]%"; // order IMPORTANT const char szIpV4AddressChars[] = "01234567890.:[]"; // order IMPORTANT const char szLinkLocalPrefix[] = "FfEe8800"; // const char *pszIpV6AddressChars = NULL, *pszIpV4AddressChars = NULL, *pszLinkLocalPrefix = NULL; char *pszSourceAddress = NULL, *pszSourceAddressStart = NULL; char *pszResultAddress = NULL, *pszResultAddressStart = NULL; char *pszResultAddress4 = NULL, *pszResultAddress4Start = NULL; char *pszResultPort = NULL, *pszResultPortStart = NULL; char *pszInternalAddress = NULL, *pszInternalAddressStart = NULL; char *pszInternalPort = NULL, *pszInternalPortStart = NULL; char *pStart = NULL, *pNow = NULL, *pNext = NULL, *pNowChar = NULL, *pIfId = NULL, *pIfIdEnd = NULL; char *pNowDigit = NULL, *pFrom = NULL, *pTo = NULL, *pLast = NULL; char *pGap = NULL, *pMisc = NULL, *pDotStart = NULL, *pFieldStart = NULL, *pFieldEnd = NULL; char *pFieldStartLongest = NULL, *pBracketOpen = NULL, *pBracketClose = NULL; char *pszRc = NULL; bool isLinkLocal = false; char szDummy[4]; uint8_t *pByte = NULL; uint32_t byteOut = 0; uint16_t returnValue = 0; uint32_t colons = 0; uint32_t colonsOverAll = 0; uint32_t fieldLength = 0; uint32_t dots = 0; size_t gapSize = 0; uint32_t intPortOut = 0; pszIpV4AddressChars = &szIpV4AddressChars[0]; pszIpV6AddressChars = &szIpV6AddressChars[6]; pszLinkLocalPrefix = &szLinkLocalPrefix[6]; if (!followRfc) pszIpV6AddressChars = &szIpV6AddressChars[0]; if (addressLength<2) returnValue = 711; pszResultAddressStart = (char *)RTMemTmpAlloc(34); pszInternalAddressStart = (char *)RTMemTmpAlloc(34); pszInternalPortStart = (char * )RTMemTmpAlloc(10); if (! (pszResultAddressStart && pszInternalAddressStart && pszInternalPortStart)) { if (pszResultAddressStart) RTMemTmpFree(pszResultAddressStart); if (pszInternalAddressStart) RTMemTmpFree(pszInternalAddressStart); if (pszInternalPortStart) RTMemTmpFree(pszInternalPortStart); return -701; } memset(szDummy, '\0', 4); pszResultAddress = pszResultAddressStart; memset(pszResultAddressStart, '\0', 34); pszInternalAddress = pszInternalAddressStart; memset(pszInternalAddressStart, '\0' , 34); pszInternalPort = pszInternalPortStart; memset(pszInternalPortStart, '\0', 10); pszSourceAddress = pszSourceAddressStart = (char *)pszAddress; pFrom = pTo = pStart = pLast = pszSourceAddressStart; while (*pszSourceAddress != '\0' && !returnValue) { pNow = NULL; pNext = NULL; pNowChar = NULL; pNowDigit = NULL; pNow = pszSourceAddress; pNext = pszSourceAddress + 1; if (!pFrom) pFrom = pTo = pNow; pNowChar = (char *)memchr(pszIpV6AddressChars, *pNow, strlen(pszIpV6AddressChars)); pNowDigit = (char *)memchr(pszIpV6AddressChars, *pNow, strlen(pszIpV6AddressChars) - 5); if (pszResultPort) { if (pLast && (pszResultPort == pszSourceAddressStart)) { if (*pLast == '\0') returnValue = 721; pszResultPortStart = (char *)RTMemTmpAlloc(10); if (!pszResultPortStart) returnValue = 702; memset(pszResultPortStart, '\0', 10); pszResultPort = pszResultPortStart; pszSourceAddress = pLast; pMisc = pLast; pLast = NULL; continue; } pNowDigit = NULL; pNowDigit = (char *)memchr(pszIpV4AddressChars, *pNow, strlen(pszIpV4AddressChars) - 4); if (strlen(pszResultPortStart) == 5) returnValue = 11; if (*pNow == '0' && pszResultPort == pszResultPortStart && *pNext != '\0' && (pNow - pMisc) < 5 ) { pszSourceAddress++; continue; } if (pNowDigit) { *pszResultPort = *pNowDigit; pszResultPort++; pszSourceAddress++; continue; } else returnValue = 12; } if (pszResultAddress4) { if (pszResultAddress4 == pszSourceAddressStart && pLast) { dots = 0; pszResultAddress4 = NULL; pszResultAddress4Start = NULL; pszResultAddress4Start = (char *)RTMemTmpAlloc(20); if (!pszResultAddress4Start) { returnValue = 401; break; } memset(pszResultAddress4Start, '\0', 20); pszResultAddress4 = pszResultAddress4Start; pszSourceAddress = pLast; pFrom = pLast; pTo = pLast; pLast = NULL; continue; } pTo = pNow; pNowDigit = NULL; pNowDigit = (char *)memchr(pszIpV4AddressChars, *pNow, strlen(pszIpV4AddressChars) - 4); if (!pNowDigit && *pNow != '.' && *pNow != ']' && *pNow != ':' && *pNow != '%') returnValue = 412; if ((pNow - pFrom) > 3) { returnValue = 402; break; } if (pNowDigit && *pNext != '\0') { pszSourceAddress++; continue; } if (!pNowDigit && !pBracketOpen && (*pNext == '.' || *pNext == ']' || *pNext == ':')) returnValue = 411; memset(pszResultAddress4, '0', 3); pMisc = pszResultAddress4 + 2; pszResultAddress4 = pszResultAddress4 + 3; if (*pNow != '.' && !pNowDigit && strlen(pszResultAddress4Start) < 9) returnValue = 403; if ((pTo - pFrom) > 0) pTo--; dots++; while (pTo >= pFrom) { *pMisc = *pTo; pMisc--; pTo--; } if (dots == 4 && *pNow == '.') { if (!pBracketOpen) { pszResultPort = pszSourceAddressStart; pLast = pNext; } else { returnValue = 409; } } dots = 0; pFrom = pNext; pTo = pNext; if (strlen(pszResultAddress4Start) > 11) pszResultAddress4 = NULL; if ((*pNow == ':' || *pNow == '.') && strlen(pszResultAddress4Start) == 12) { pLast = pNext; pszResultPort = pszSourceAddressStart; } if (*pNow == '%') { pIfId = pNow; pLast = pNow; continue; } pszSourceAddress = pNext; if (*pNow != ']') continue; pFrom = pNow; pTo = pNow; } if (pIfId && (!pIfIdEnd)) { if (*pIfId == '%' && pIfId == pLast && *pNext != '\0') { pFrom = pNext; pIfId = pNext; pLast = NULL; pszSourceAddress++; continue; } if (*pNow == '%' && pIfId <= pNow) { returnValue = 442; break; } if (*pNow != ']' && *pNext != '\0') { pTo = pNow; pszSourceAddress++; continue; } if (*pNow == ']') { pIfIdEnd = pNow - 1; pFrom = pNow; pTo = pNow; continue; } else { pIfIdEnd = pNow; pFrom = NULL; pTo = NULL; pszSourceAddress++; continue; } } if (!pNowChar) { returnValue = 254; if (followRfc) { pMisc = (char *)memchr(&szIpV6AddressChars[0], *pNow, strlen(&szIpV6AddressChars[0])); if (pMisc) returnValue = 253; } } if (strlen(pszResultAddressStart) > 32 && !pszResultAddress4Start) returnValue = 255; if (pNowDigit && *pNext != '\0' && colons == 0) { pTo = pNow; pszSourceAddress++; continue; } if (*pNow == ':' && *pNext != '\0') { colonsOverAll++; colons++; pszSourceAddress++; continue; } if (*pNow == ':' ) { colons++; colonsOverAll++; } if (*pNow == '.') { pMisc = pNow; while (*pMisc != '\0' && *pMisc != ']') { if (*pMisc == '.') dots++; pMisc++; } } if (*pNow == ']') { if (pBracketClose) returnValue = 77; if (!pBracketOpen) returnValue = 22; if (*pNext == ':' || *pNext == '.') { pszResultPort = pszSourceAddressStart; pLast = pNext + 1; } if (pFrom == pNow) pFrom = NULL; pBracketClose = pNow; } if (*pNow == '[') { if (pBracketOpen) returnValue = 23; if (pStart != pNow) returnValue = 24; pBracketOpen = pNow; pStart++; pFrom++; pszSourceAddress++; continue; } if (*pNow == '%') { if (pIfId) returnValue = 441; pLast = pNext; pIfId = pNext; } if (colons > 0) { if (colons == 1) { if (pStart + 1 == pNow ) returnValue = 31; if (*pNext == '\0' && !pNowDigit) returnValue = 32; pLast = pNow; } if (colons == 2) { if (pGap) returnValue = 33; pGap = pszResultAddress + 4; if (pStart + 1 == pNow || pStart + 2 == pNow) { pGap = pszResultAddressStart; pFrom = pNow; } if (*pNext == '\0' && !pNowDigit) pszSourceAddress++; if (*pNext != ':' && *pNext != '.') pLast = pNow; } if (colons == 3) { pFrom = pLast; pLast = pNow; if (*pNext == '\0' && !pNowDigit) returnValue = 34; if (pBracketOpen) returnValue = 35; if (pGap && followRfc) returnValue = 36; if (!pGap) pGap = pszResultAddress + 4; if (pStart + 3 == pNow) { pszResultPort = pszSourceAddressStart; pGap = pszResultAddress; pFrom = NULL; } if (pNowDigit) { pszResultPort = pszSourceAddressStart; } } } if (*pNext == '\0' && colons == 0 && !pIfIdEnd) { pFrom = pLast; if (pNowDigit) pTo = pNow; pLast = NULL; } if (dots > 0) { if (dots == 1) { pszResultPort = pszSourceAddressStart; pLast = pNext; } if (dots == 4 && pBracketOpen) returnValue = 601; if (dots == 3 || dots == 4) { pszResultAddress4 = pszSourceAddressStart; pLast = pFrom; pFrom = NULL; } if (dots > 4) returnValue = 603; dots = 0; } if (pFrom && pTo) { if (pTo - pFrom > 3) { returnValue = 51; break; } if (followRfc) { if ((pTo - pFrom > 0) && *pFrom == '0') returnValue = 101; if ((pTo - pFrom) == 0 && *pFrom == '0' && colons == 2) returnValue = 102; if ((pTo - pFrom) == 0 && *pFrom == '0' && pszResultAddress == pGap) returnValue = 103; if ((pTo - pFrom) == 0 && *pFrom == '0') { if (!pFieldStart) { pFieldStart = pszResultAddress; pFieldEnd = pszResultAddress + 4; } else { pFieldEnd = pFieldEnd + 4; } } else { if ((size_t)(pFieldEnd - pFieldStart) > fieldLength) { fieldLength = pFieldEnd - pFieldStart; pFieldStartLongest = pFieldStart; } pFieldStart = NULL; pFieldEnd = NULL; } } if (!(pGap == pszResultAddressStart && (size_t)(pNow - pStart) == colons)) { memset(pszResultAddress, '0', 4); pMisc = pszResultAddress + 3; pszResultAddress = pszResultAddress + 4; if (pFrom == pStart && (pTo - pFrom) == 3) { isLinkLocal = true; while (pTo >= pFrom) { *pMisc = *pTo; if (*pTo != *pszLinkLocalPrefix && *pTo != *(pszLinkLocalPrefix + 1)) isLinkLocal = false; pTo--; pMisc--; pszLinkLocalPrefix = pszLinkLocalPrefix - 2; } } else { while (pTo >= pFrom) { *pMisc = *pTo; pMisc--; pTo--; } } } pFrom = pNow; pTo = pNow; } if (*pNext == '\0' && colons == 0) pszSourceAddress++; if (*pNext == '\0' && !pBracketClose && !pszResultPort) pTo = pNext; colons = 0; } // end of loop if (!returnValue && colonsOverAll < 2) returnValue = 252; if (!returnValue && (pBracketOpen && !pBracketClose)) returnValue = 25; if (!returnValue && pGap) { gapSize = 32 - strlen(pszResultAddressStart); if (followRfc) { if (gapSize < 5) returnValue = 104; if (fieldLength > gapSize) returnValue = 105; if (fieldLength == gapSize && pFieldStartLongest < pGap) returnValue = 106; } pszResultAddress = pszResultAddressStart; pszInternalAddress = pszInternalAddressStart; if (!returnValue && pszResultAddress4Start) { if (strlen(pszResultAddressStart) > 4) returnValue = 405; pszResultAddress = pszResultAddressStart; if (pGap != pszResultAddressStart) returnValue = 407; memset(pszInternalAddressStart, '0', 20); pszInternalAddress = pszInternalAddressStart + 20; for (int i = 0; i < 4; i++) { if (*pszResultAddress != 'f' && *pszResultAddress != 'F') { returnValue = 406; break; } *pszInternalAddress = *pszResultAddress; pszResultAddress++; pszInternalAddress++; } pszResultAddress4 = pszResultAddress4Start; for (int i = 0; i<4; i++) { memcpy(szDummy, pszResultAddress4, 3); int rc = RTStrToUInt32Ex((const char *)&szDummy[0], NULL, 16, &byteOut); if (rc == 0 && byteOut < 256) { RTStrPrintf(szDummy, 3, "%02x", byteOut); memcpy(pszInternalAddress, szDummy, 2); pszInternalAddress = pszInternalAddress + 2; pszResultAddress4 = pszResultAddress4 + 3; memset(szDummy, '\0', 4); } else { returnValue = 499; } } } else { while (!returnValue && pszResultAddress != pGap) { *pszInternalAddress = *pszResultAddress; pszResultAddress++; pszInternalAddress++; } memset(pszInternalAddress, '0', gapSize); pszInternalAddress = pszInternalAddress + gapSize; while (!returnValue && *pszResultAddress != '\0') { *pszInternalAddress = *pszResultAddress; pszResultAddress++; pszInternalAddress++; } } } else { if (!returnValue) { if (strlen(pszResultAddressStart) != 32) returnValue = 111; if (followRfc) { if (fieldLength > 4) returnValue = 112; } memcpy(pszInternalAddressStart, pszResultAddressStart, strlen(pszResultAddressStart)); } } if (pszResultPortStart) { if (strlen(pszResultPortStart) > 0 && strlen(pszResultPortStart) < 6) { memcpy(pszInternalPortStart, pszResultPortStart, strlen(pszResultPortStart)); intPortOut = 0; int rc = RTStrToUInt32Ex(pszInternalPortStart, NULL, 10, &intPortOut); if (rc == 0) { if (!(intPortOut > 0 && intPortOut < 65536)) intPortOut = 0; } else { returnValue = 888; } } else { returnValue = 889; } } /* full blown address 32 bytes, no colons -> pszInternalAddressStart port as string -> pszResultPortStart port as binary integer -> intPortOut interface id in pIfId and pIfIdEnd Now fill the out parameters. */ if (!returnValue && pszAddressOut) { if (strlen(pszInternalAddressStart) < addressOutSize) { pszRc = NULL; pszRc = (char *)memset(pszAddressOut, '\0', addressOutSize); if (!pszRc) returnValue = 910; pszRc = NULL; pszRc = (char *)memcpy(pszAddressOut, pszInternalAddressStart, strlen(pszInternalAddressStart)); if (!pszRc) returnValue = 911; } else { returnValue = 912; } } if (!returnValue && pPortOut) { *pPortOut = intPortOut; } if (!returnValue && pszIfIdOut) { if (pIfIdEnd && pIfId) { if ((size_t)(pIfIdEnd - pIfId) + 1 < ifIdOutSize) { pszRc = NULL; pszRc = (char *)memset(pszIfIdOut, '\0', ifIdOutSize); if (!pszRc) returnValue = 913; pszRc = NULL; pszRc = (char *)memcpy(pszIfIdOut, pIfId, (pIfIdEnd - pIfId) + 1); if (!pszRc) returnValue = 914; } else { returnValue = 915; } } else { pszRc = NULL; pszRc = (char *)memset(pszIfIdOut, '\0', ifIdOutSize); if (!pszRc) returnValue = 916; } // temporary hack if (isLinkLocal && (strlen(pszIfIdOut) < 1)) { memset(pszIfIdOut, '\0', ifIdOutSize); *pszIfIdOut = '%'; pszIfIdOut++; *pszIfIdOut = '0'; pszIfIdOut++; } } if (pBracketOpen && pBracketClose && pBrackets) *pBrackets = true; if (pEmbeddedV4 && pszResultAddress4Start) *pEmbeddedV4 = true; if (pszResultAddressStart) RTMemTmpFree(pszResultAddressStart); if (pszResultPortStart) RTMemTmpFree(pszResultPortStart); if (pszResultAddress4Start) RTMemTmpFree(pszResultAddress4Start); if (pszInternalAddressStart) RTMemTmpFree(pszInternalAddressStart); if (pszInternalPortStart) RTMemTmpFree(pszInternalPortStart); return (uint32_t)(returnValue - (returnValue * 2)); // make it negative... }
/** * Worker for VbgdDarwinIOCtl that takes the slow IOCtl functions. * * @returns Darwin errno. * * @param pSession The session. * @param iCmd The IOCtl command. * @param pData Pointer to the kernel copy of the data buffer. * @param pProcess The calling process. */ static int VbgdDarwinIOCtlSlow(PVBOXGUESTSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess) { LogFlow(("VbgdDarwinIOCtlSlow: pSession=%p iCmd=%p pData=%p pProcess=%p\n", pSession, iCmd, pData, pProcess)); /* * Buffered or unbuffered? */ void *pvReqData; user_addr_t pUser = 0; void *pvPageBuf = NULL; uint32_t cbReq = IOCPARM_LEN(iCmd); if ((IOC_DIRMASK & iCmd) == IOC_INOUT) { /* * Raw buffered request data, common code validates it. */ pvReqData = pData; } else if ((IOC_DIRMASK & iCmd) == IOC_VOID && !cbReq) { /* * Get the header and figure out how much we're gonna have to read. */ VBGLBIGREQ Hdr; pUser = (user_addr_t)*(void **)pData; int rc = copyin(pUser, &Hdr, sizeof(Hdr)); if (RT_UNLIKELY(rc)) { Log(("VbgdDarwinIOCtlSlow: copyin(%llx,Hdr,) -> %#x; iCmd=%#lx\n", (unsigned long long)pUser, rc, iCmd)); return rc; } if (RT_UNLIKELY(Hdr.u32Magic != VBGLBIGREQ_MAGIC)) { Log(("VbgdDarwinIOCtlSlow: bad magic u32Magic=%#x; iCmd=%#lx\n", Hdr.u32Magic, iCmd)); return EINVAL; } cbReq = Hdr.cbData; if (RT_UNLIKELY(cbReq > _1M*16)) { Log(("VbgdDarwinIOCtlSlow: %#x; iCmd=%#lx\n", Hdr.cbData, iCmd)); return EINVAL; } pUser = Hdr.pvDataR3; /* * Allocate buffer and copy in the data. */ pvReqData = RTMemTmpAlloc(cbReq); if (!pvReqData) pvPageBuf = pvReqData = IOMallocAligned(RT_ALIGN_Z(cbReq, PAGE_SIZE), 8); if (RT_UNLIKELY(!pvReqData)) { Log(("VbgdDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cbReq, iCmd)); return ENOMEM; } rc = copyin(pUser, pvReqData, Hdr.cbData); if (RT_UNLIKELY(rc)) { Log(("VbgdDarwinIOCtlSlow: copyin(%llx,%p,%#x) -> %#x; iCmd=%#lx\n", (unsigned long long)pUser, pvReqData, Hdr.cbData, rc, iCmd)); if (pvPageBuf) IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE)); else RTMemTmpFree(pvReqData); return rc; } } else { Log(("VbgdDarwinIOCtlSlow: huh? cbReq=%#x iCmd=%#lx\n", cbReq, iCmd)); return EINVAL; } /* * Process the IOCtl. */ size_t cbReqRet = 0; int rc = VBoxGuestCommonIOCtl(iCmd, &g_DevExt, pSession, pvReqData, cbReq, &cbReqRet); if (RT_SUCCESS(rc)) { /* * If not buffered, copy back the buffer before returning. */ if (pUser) { if (cbReqRet > cbReq) { Log(("VbgdDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbReqRet, cbReq, iCmd)); cbReqRet = cbReq; } rc = copyout(pvReqData, pUser, cbReqRet); if (RT_UNLIKELY(rc)) Log(("VbgdDarwinIOCtlSlow: copyout(%p,%llx,%#x) -> %d; uCmd=%#lx!\n", pvReqData, (unsigned long long)pUser, cbReqRet, rc, iCmd)); /* cleanup */ if (pvPageBuf) IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE)); else RTMemTmpFree(pvReqData); } else rc = 0; } else { /* * The request failed, just clean up. */ if (pUser) { if (pvPageBuf) IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE)); else RTMemTmpFree(pvReqData); } Log(("VbgdDarwinIOCtlSlow: pid=%d iCmd=%lx pData=%p failed, rc=%d\n", proc_pid(pProcess), iCmd, (void *)pData, rc)); rc = EINVAL; } Log2(("VbgdDarwinIOCtlSlow: returns %d\n", rc)); return rc; }
static void tstObjectCreateTemp(const char *pszSubTest, const char *pszTemplate, bool fFile, RTFMODE fMode, unsigned cTimes, bool fSkipXCheck) { RTTestISub(pszSubTest); const char *pcszAPI = fFile ? "RTFileCreateTemp" : "RTDirCreateTemp"; /* Allocate the result array. */ char **papszNames = (char **)RTMemTmpAllocZ(cTimes * sizeof(char *)); RTTESTI_CHECK_RETV(papszNames != NULL); /* The test loop. */ unsigned i; for (i = 0; i < cTimes; i++) { int rc; char szName[RTPATH_MAX]; RTFMODE fModeFinal; RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), pszTemplate), VINF_SUCCESS); if (RT_FAILURE(rc)) break; RTTESTI_CHECK(papszNames[i] = RTStrDup(szName)); if (!papszNames[i]) break; rc = fFile ? RTFileCreateTemp(papszNames[i], fMode) : RTDirCreateTemp(papszNames[i], fMode); if (rc != VINF_SUCCESS) { RTTestIFailed("%s(%s, %#o) call #%u -> %Rrc\n", pcszAPI, szName, (int)fMode, i, rc); RTStrFree(papszNames[i]); papszNames[i] = NULL; break; } /* Check that the final permissions are not more permissive than * the ones requested (less permissive is fine, c.f. umask etc.). * I mask out the group as I am not sure how we deal with that on * Windows. */ RTTESTI_CHECK_RC_OK(rc = RTPathGetMode(papszNames[i], &fModeFinal)); if (RT_SUCCESS(rc)) { fModeFinal &= (RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXO); RTTESTI_CHECK_MSG((fModeFinal & ~fMode) == 0, ("%s: szName %s\nfModeFinal ~= %#o, expected %#o\n", pcszAPI, szName, fModeFinal, (int)fMode)); } RTTestIPrintf(RTTESTLVL_DEBUG, "%s: %s\n", pcszAPI, papszNames[i]); RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("%s: szName %s\nReturned %s\n", pcszAPI, szName, papszNames[i])); if (!fSkipXCheck) RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, ("%s: szName %s\nReturned %s\n", pcszAPI, szName, papszNames[i])); } /* cleanup */ while (i-- > 0) { if (fFile) RTTESTI_CHECK_RC(RTFileDelete(papszNames[i]), VINF_SUCCESS); else RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); RTStrFree(papszNames[i]); } RTMemTmpFree(papszNames); }
/** * Worker for VBoxSupDrvIOCtl that takes the slow IOCtl functions. * * @returns Solaris errno. * * @param pSession The session. * @param Cmd The IOCtl command. * @param Mode Information bitfield (for specifying ownership of data) * @param iArg User space address of the request buffer. */ static int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int iCmd, int Mode, intptr_t iArg) { int rc; uint32_t cbBuf = 0; union { SUPREQHDR Hdr; uint8_t abBuf[64]; } StackBuf; PSUPREQHDR pHdr; /* * Read the header. */ if (RT_UNLIKELY(IOCPARM_LEN(iCmd) != sizeof(StackBuf.Hdr))) { LogRel(("VBoxDrvSolarisIOCtlSlow: iCmd=%#x len %d expected %d\n", iCmd, IOCPARM_LEN(iCmd), sizeof(StackBuf.Hdr))); return EINVAL; } rc = ddi_copyin((void *)iArg, &StackBuf.Hdr, sizeof(StackBuf.Hdr), Mode); if (RT_UNLIKELY(rc)) { LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyin(,%#lx,) failed; iCmd=%#x. rc=%d\n", iArg, iCmd, rc)); return EFAULT; } if (RT_UNLIKELY((StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) != SUPREQHDR_FLAGS_MAGIC)) { LogRel(("VBoxDrvSolarisIOCtlSlow: bad header magic %#x; iCmd=%#x\n", StackBuf.Hdr.fFlags & SUPREQHDR_FLAGS_MAGIC_MASK, iCmd)); return EINVAL; } cbBuf = RT_MAX(StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut); if (RT_UNLIKELY( StackBuf.Hdr.cbIn < sizeof(StackBuf.Hdr) || StackBuf.Hdr.cbOut < sizeof(StackBuf.Hdr) || cbBuf > _1M*16)) { LogRel(("VBoxDrvSolarisIOCtlSlow: max(%#x,%#x); iCmd=%#x\n", StackBuf.Hdr.cbIn, StackBuf.Hdr.cbOut, iCmd)); return EINVAL; } /* * Buffer the request. */ if (cbBuf <= sizeof(StackBuf)) pHdr = &StackBuf.Hdr; else { pHdr = RTMemTmpAlloc(cbBuf); if (RT_UNLIKELY(!pHdr)) { LogRel(("VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes for iCmd=%#x.\n", cbBuf, iCmd)); return ENOMEM; } } rc = ddi_copyin((void *)iArg, pHdr, cbBuf, Mode); if (RT_UNLIKELY(rc)) { LogRel(("VBoxDrvSolarisIOCtlSlow: copy_from_user(,%#lx, %#x) failed; iCmd=%#x. rc=%d\n", iArg, cbBuf, iCmd, rc)); if (pHdr != &StackBuf.Hdr) RTMemFree(pHdr); return EFAULT; } /* * Process the IOCtl. */ rc = supdrvIOCtl(iCmd, &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)) { LogRel(("VBoxDrvSolarisIOCtlSlow: too much output! %#x > %#x; iCmd=%#x!\n", cbOut, cbBuf, iCmd)); cbOut = cbBuf; } rc = ddi_copyout(pHdr, (void *)iArg, cbOut, Mode); if (RT_UNLIKELY(rc != 0)) { /* this is really bad */ LogRel(("VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed. rc=%d\n", (void *)iArg, cbBuf, rc)); rc = EFAULT; } } else rc = EINVAL; if (pHdr != &StackBuf.Hdr) RTMemTmpFree(pHdr); return rc; }
RTDECL(int) RTCrStoreCertAddWantedFromFishingExpedition(RTCRSTORE hStore, uint32_t fFlags, PCRTCRCERTWANTED paWanted, size_t cWanted, bool *pafFound, PRTERRINFO pErrInfo) { int rc = VINF_SUCCESS; int rc2; /* * Validate input. */ AssertReturn(!(fFlags & ~(RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR)), VERR_INVALID_FLAGS); fFlags |= RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR; /* force these! */ AssertReturn(cWanted, VERR_NOT_FOUND); for (uint32_t i = 0; i < cWanted; i++) { AssertReturn(!paWanted[i].pszSubject || *paWanted[i].pszSubject, VERR_INVALID_PARAMETER); AssertReturn( paWanted[i].pszSubject || paWanted[i].fSha1Fingerprint || paWanted[i].fSha512Fingerprint, VERR_INVALID_PARAMETER); } /* * Make sure we've got a result array. */ bool *pafFoundFree = NULL; if (!pafFound) { pafFound = pafFoundFree = (bool *)RTMemTmpAllocZ(sizeof(bool) * cWanted); AssertReturn(pafFound, VERR_NO_TMP_MEMORY); } /* * Search the user and system stores first. */ bool fAllFound = false; RTCRSTORE hTmpStore; for (int iStoreId = RTCRSTOREID_INVALID + 1; iStoreId < RTCRSTOREID_END; iStoreId++) { rc2 = RTCrStoreCreateSnapshotById(&hTmpStore, (RTCRSTOREID)iStoreId, NULL); if (RT_SUCCESS(rc2)) { rc2 = RTCrStoreCertAddWantedFromStore(hStore, fFlags, hTmpStore, paWanted, cWanted, pafFound); RTCrStoreRelease(hTmpStore); fAllFound = rc2 == VINF_SUCCESS; if (fAllFound) break; } } /* * Search alternative file based stores. */ if (!fAllFound) { static const char * const s_apszFiles[] = { PREFIX_UNIXROOT "/usr/share/ca-certificates/trust-source/mozilla.neutral-trust.crt", PREFIX_UNIXROOT "/usr/share/ca-certificates/trust-source/mozilla.trust.crt", PREFIX_UNIXROOT "/usr/share/doc/mutt/samples/ca-bundle.crt", PREFIX_UNIXROOT "/usr/jdk/latest/jre/lib/security/cacerts", PREFIX_UNIXROOT "/usr/share/curl/curl-ca-bundle.crt", #ifdef RT_OS_DARWIN "/opt/local/share/curl/curl-ca-bundle.crt", "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts", "/System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security/cacerts", "/System/Library/Java/Support/CoreDeploy.bundle/Contents/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts", "/System/Library/Java/Support/Deploy.bundle/Contents/Home/lib/security/cacerts", "/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/lib/security/cacerts", "/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/itms/java/lib/security/cacerts", "/Applications/Xcode-beta.app/Contents/Applications/Application Loader.app/Contents/itms/java/lib/security/cacerts", "/System/Library/Java/JavaVirtualMachines/*/Contents/Home/lib/security/cacerts", #endif #ifdef RT_OS_LINUX PREFIX_UNIXROOT "/etc/ssl/certs/java/cacerts", PREFIX_UNIXROOT "/usr/lib/j*/*/jre/lib/security/cacerts", PREFIX_UNIXROOT "/opt/*/jre/lib/security/cacerts", #endif #ifdef RT_OS_SOLARIS PREFIX_UNIXROOT "/usr/java/jre/lib/security/cacerts", PREFIX_UNIXROOT "/usr/jdk/instances/*/jre/lib/security/cacerts", #endif #ifdef RT_OS_WINDOWS "${AllProgramFiles}/Git/bin/curl-ca-bundle.crt", "${AllProgramFiles}/Mercurial/hgrc.d/cacert.pem", "${AllProgramFiles}/Java/jre*/lib/security/cacerts", "${AllProgramFiles}/Java/jdk*/jre/lib/security/cacerts", "${AllProgramFiles}/HexChat/cert.pem", "${SystemDrive}/BitNami/*/git/bin/curl-ca-bundle.crt", "${SystemDrive}/BitNami/*/heroku/data/cacert.pem", "${SystemDrive}/BitNami/*/heroku/vendor/gems/excon*/data/cacert.pem", "${SystemDrive}/BitNami/*/php/PEAR/AWSSDKforPHP/lib/requstcore/cacert.pem", #endif }; for (uint32_t i = 0; i < RT_ELEMENTS(s_apszFiles) && !fAllFound; i++) { PCRTPATHGLOBENTRY pResultHead; rc2 = RTPathGlob(s_apszFiles[i], RTPATHGLOB_F_NO_DIRS, &pResultHead, NULL); if (RT_SUCCESS(rc2)) { for (PCRTPATHGLOBENTRY pCur = pResultHead; pCur; pCur = pCur->pNext) { rc2 = RTCrStoreCertAddWantedFromFile(hStore, fFlags, pCur->szPath, paWanted, cWanted, pafFound, pErrInfo); fAllFound = rc2 == VINF_SUCCESS; if (fAllFound) break; } RTPathGlobFree(pResultHead); } } } /* * Search alternative directory based stores. */ if (!fAllFound) { static const char * const s_apszFiles[] = { PREFIX_UNIXROOT "/usr/share/ca-certificates/mozilla/", #ifdef RT_OS_DARWIN "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/ssl_certs/", #endif #ifdef RT_OS_SOLARIS "/etc/certs/", "/etc/crypto/certs/", #endif #ifdef RT_OS_WINDOWS "${AllProgramFiles}/Git/ssl/certs/", "${AllProgramFiles}/Git/ssl/certs/expired/", "${AllProgramFiles}/Common Files/Apple/Internet Services/security.resources/roots/", "${AllProgramFiles}/Raptr/ca-certs/", "${SystemDrive}/Bitname/*/git/ssl/certs/", "${SystemDrive}/Bitnami/*/git/ssl/certs/expired/", #endif }; for (uint32_t i = 0; i < RT_ELEMENTS(s_apszFiles) && !fAllFound; i++) { PCRTPATHGLOBENTRY pResultHead; rc2 = RTPathGlob(s_apszFiles[i], RTPATHGLOB_F_ONLY_DIRS, &pResultHead, NULL); if (RT_SUCCESS(rc2)) { for (PCRTPATHGLOBENTRY pCur = pResultHead; pCur; pCur = pCur->pNext) { rc2 = RTCrStoreCertAddWantedFromDir(hStore, fFlags, pCur->szPath, NULL /*paSuffixes*/, 0 /*cSuffixes*/, paWanted, cWanted, pafFound, pErrInfo); fAllFound = rc2 == VINF_SUCCESS; if (fAllFound) break; } RTPathGlobFree(pResultHead); } } } /* * If all found, return VINF_SUCCESS, otherwise warn that we didn't find everything. */ if (RT_SUCCESS(rc)) { size_t cFound = rtCrStoreCountFound(pafFound, cWanted); Assert(cFound == cWanted || !fAllFound); if (cFound == cWanted) rc = VINF_SUCCESS; else if (cFound > 0) rc = VWRN_NOT_FOUND; else rc = VERR_NOT_FOUND; } if (pafFoundFree) RTMemTmpFree(pafFoundFree); return rc; }
/** * Converts a string from one charset to another without using the handle cache. * * @returns IPRT status code. * * @param pvInput Pointer to intput string. * @param cbInput Size (in bytes) of input string. Excludes any terminators. * @param pszInputCS Codeset of the input string. * @param ppvOutput Pointer to pointer to output buffer if cbOutput > 0. * If cbOutput is 0 this is where the pointer to the allocated * buffer is stored. * @param cbOutput Size of the passed in buffer. * @param pszOutputCS Codeset of the input string. * @param cFactor Input vs. output size factor. */ static int rtStrConvertUncached(const void *pvInput, size_t cbInput, const char *pszInputCS, void **ppvOutput, size_t cbOutput, const char *pszOutputCS, unsigned cFactor) { /* * Allocate buffer */ bool fUcs2Term; void *pvOutput; size_t cbOutput2; if (!cbOutput) { cbOutput2 = cbInput * cFactor; pvOutput = RTMemTmpAlloc(cbOutput2 + sizeof(RTUTF16)); if (!pvOutput) return VERR_NO_TMP_MEMORY; fUcs2Term = true; } else { pvOutput = *ppvOutput; fUcs2Term = !strcmp(pszOutputCS, "UCS-2"); cbOutput2 = cbOutput - (fUcs2Term ? sizeof(RTUTF16) : 1); if (cbOutput2 > cbOutput) return VERR_BUFFER_OVERFLOW; } /* * Use a loop here to retry with bigger buffers. */ for (unsigned cTries = 10; cTries > 0; cTries--) { /* * Create conversion object. */ #if defined(RT_OS_SOLARIS) || defined(RT_OS_NETBSD) /* Some systems don't grok empty codeset strings, so help them find the current codeset. */ if (!*pszInputCS) pszInputCS = rtStrGetLocaleCodeset(); if (!*pszOutputCS) pszOutputCS = rtStrGetLocaleCodeset(); #endif IPRT_ALIGNMENT_CHECKS_DISABLE(); /* glibc causes trouble */ iconv_t icHandle = iconv_open(pszOutputCS, pszInputCS); IPRT_ALIGNMENT_CHECKS_ENABLE(); if (icHandle != (iconv_t)-1) { /* * Do the conversion. */ size_t cbInLeft = cbInput; size_t cbOutLeft = cbOutput2; const void *pvInputLeft = pvInput; void *pvOutputLeft = pvOutput; size_t cchNonRev; #if defined(RT_OS_LINUX) || defined(RT_OS_HAIKU) || defined(RT_OS_SOLARIS) || (defined(RT_OS_DARWIN) && defined(_DARWIN_FEATURE_UNIX_CONFORMANCE)) /* there are different opinions about the constness of the input buffer. */ cchNonRev = iconv(icHandle, (char **)&pvInputLeft, &cbInLeft, (char **)&pvOutputLeft, &cbOutLeft); #else cchNonRev = iconv(icHandle, (const char **)&pvInputLeft, &cbInLeft, (char **)&pvOutputLeft, &cbOutLeft); #endif if (cchNonRev != (size_t)-1) { if (!cbInLeft) { /* * We're done, just add the terminator and return. * (Two terminators to support UCS-2 output, too.) */ iconv_close(icHandle); ((char *)pvOutputLeft)[0] = '\0'; if (fUcs2Term) ((char *)pvOutputLeft)[1] = '\0'; *ppvOutput = pvOutput; if (cchNonRev == 0) return VINF_SUCCESS; return VWRN_NO_TRANSLATION; } errno = E2BIG; } iconv_close(icHandle); /* * If we failed because of output buffer space we'll * increase the output buffer size and retry. */ if (errno == E2BIG) { if (!cbOutput) { RTMemTmpFree(pvOutput); cbOutput2 *= 2; pvOutput = RTMemTmpAlloc(cbOutput2 + sizeof(RTUTF16)); if (!pvOutput) return VERR_NO_TMP_MEMORY; continue; } return VERR_BUFFER_OVERFLOW; } } break; } /* failure */ if (!cbOutput) RTMemTmpFree(pvOutput); return VERR_NO_TRANSLATION; }
int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename) { pImage->pvNtSectionObj = NULL; pImage->hMemLock = NIL_RTR0MEMOBJ; #ifdef VBOX_WITHOUT_NATIVE_R0_LOADER # ifndef RT_ARCH_X86 # error "VBOX_WITHOUT_NATIVE_R0_LOADER is only safe on x86." # endif NOREF(pDevExt); NOREF(pszFilename); NOREF(pImage); return VERR_NOT_SUPPORTED; #else /* * Convert the filename from DOS UTF-8 to NT UTF-16. */ size_t cwcFilename; int rc = RTStrCalcUtf16LenEx(pszFilename, RTSTR_MAX, &cwcFilename); if (RT_FAILURE(rc)) return rc; PRTUTF16 pwcsFilename = (PRTUTF16)RTMemTmpAlloc((4 + cwcFilename + 1) * sizeof(RTUTF16)); if (!pwcsFilename) return VERR_NO_TMP_MEMORY; pwcsFilename[0] = '\\'; pwcsFilename[1] = '?'; pwcsFilename[2] = '?'; pwcsFilename[3] = '\\'; PRTUTF16 pwcsTmp = &pwcsFilename[4]; rc = RTStrToUtf16Ex(pszFilename, RTSTR_MAX, &pwcsTmp, cwcFilename + 1, NULL); if (RT_SUCCESS(rc)) { /* * Try load it. */ MYSYSTEMGDIDRIVERINFO Info; RtlInitUnicodeString(&Info.Name, pwcsFilename); Info.ImageAddress = NULL; Info.SectionPointer = NULL; Info.EntryPointer = NULL; Info.ExportSectionPointer = NULL; Info.ImageLength = 0; NTSTATUS rcNt = ZwSetSystemInformation(MY_SystemLoadGdiDriverInSystemSpaceInformation, &Info, sizeof(Info)); if (NT_SUCCESS(rcNt)) { pImage->pvImage = Info.ImageAddress; pImage->pvNtSectionObj = Info.SectionPointer; Log(("ImageAddress=%p SectionPointer=%p ImageLength=%#x cbImageBits=%#x rcNt=%#x '%ls'\n", Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer)); # ifdef DEBUG_bird SUPR0Printf("ImageAddress=%p SectionPointer=%p ImageLength=%#x cbImageBits=%#x rcNt=%#x '%ws'\n", Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer); # endif if (pImage->cbImageBits == Info.ImageLength) { /* * Lock down the entire image, just to be on the safe side. */ rc = RTR0MemObjLockKernel(&pImage->hMemLock, pImage->pvImage, pImage->cbImageBits, RTMEM_PROT_READ); if (RT_FAILURE(rc)) { pImage->hMemLock = NIL_RTR0MEMOBJ; supdrvOSLdrUnload(pDevExt, pImage); } } else { supdrvOSLdrUnload(pDevExt, pImage); rc = VERR_LDR_MISMATCH_NATIVE; } } else { Log(("rcNt=%#x '%ls'\n", rcNt, pwcsFilename)); SUPR0Printf("VBoxDrv: rcNt=%x '%ws'\n", rcNt, pwcsFilename); switch (rcNt) { case /* 0xc0000003 */ STATUS_INVALID_INFO_CLASS: # ifdef RT_ARCH_AMD64 /* Unwind will crash and BSOD, so no fallback here! */ rc = VERR_NOT_IMPLEMENTED; # else /* * Use the old way of loading the modules. * * Note! We do *NOT* try class 26 because it will probably * not work correctly on terminal servers and such. */ rc = VERR_NOT_SUPPORTED; # endif break; case /* 0xc0000034 */ STATUS_OBJECT_NAME_NOT_FOUND: rc = VERR_MODULE_NOT_FOUND; break; case /* 0xC0000263 */ STATUS_DRIVER_ENTRYPOINT_NOT_FOUND: rc = VERR_LDR_IMPORTED_SYMBOL_NOT_FOUND; break; case 0xC0000428 /* STATUS_INVALID_IMAGE_HASH */ : rc = VERR_LDR_IMAGE_HASH; break; case 0xC000010E /* STATUS_IMAGE_ALREADY_LOADED */ : Log(("WARNING: see @bugref{4853} for cause of this failure on Windows 7 x64\n")); rc = VERR_ALREADY_LOADED; break; default: rc = VERR_LDR_GENERAL_FAILURE; break; } pImage->pvNtSectionObj = NULL; } } RTMemTmpFree(pwcsFilename); NOREF(pDevExt); return rc; #endif }
/** * Deal with the 'slow' I/O control requests. * * @returns 0 on success, appropriate errno on failure. * @param pSession The session. * @param ulCmd The command. * @param pvData The request data. * @param pTd The calling thread. */ static int vgdrvFreeBSDIOCtlSlow(PVBOXGUESTSESSION pSession, u_long ulCmd, caddr_t pvData, struct thread *pTd) { PVBGLREQHDR pHdr; uint32_t cbReq = IOCPARM_LEN(ulCmd); void *pvUser = NULL; /* * Buffered request? */ if ((IOC_DIRMASK & ulCmd) == IOC_INOUT) { pHdr = (PVBGLREQHDR)pvData; if (RT_UNLIKELY(cbReq < sizeof(*pHdr))) { LogRel(("vgdrvFreeBSDIOCtlSlow: cbReq=%#x < %#x; ulCmd=%#lx\n", cbReq, (int)sizeof(*pHdr), ulCmd)); return EINVAL; } if (RT_UNLIKELY(pHdr->uVersion != VBGLREQHDR_VERSION)) { LogRel(("vgdrvFreeBSDIOCtlSlow: bad uVersion=%#x; ulCmd=%#lx\n", pHdr->uVersion, ulCmd)); return EINVAL; } if (RT_UNLIKELY( RT_MAX(pHdr->cbIn, pHdr->cbOut) != cbReq || pHdr->cbIn < sizeof(*pHdr) || (pHdr->cbOut < sizeof(*pHdr) && pHdr->cbOut != 0))) { LogRel(("vgdrvFreeBSDIOCtlSlow: max(%#x,%#x) != %#x; ulCmd=%#lx\n", pHdr->cbIn, pHdr->cbOut, cbReq, ulCmd)); return EINVAL; } } /* * Big unbuffered request? */ else if ((IOC_DIRMASK & ulCmd) == IOC_VOID && !cbReq) { /* * Read the header, validate it and figure out how much that needs to be buffered. */ VBGLREQHDR Hdr; pvUser = *(void **)pvData; int rc = copyin(pvUser, &Hdr, sizeof(Hdr)); if (RT_UNLIKELY(rc)) { LogRel(("vgdrvFreeBSDIOCtlSlow: copyin(%p,Hdr,) -> %#x; ulCmd=%#lx\n", pvUser, rc, ulCmd)); return rc; } if (RT_UNLIKELY(Hdr.uVersion != VBGLREQHDR_VERSION)) { LogRel(("vgdrvFreeBSDIOCtlSlow: bad uVersion=%#x; ulCmd=%#lx\n", Hdr.uVersion, ulCmd)); return EINVAL; } cbReq = RT_MAX(Hdr.cbIn, Hdr.cbOut); if (RT_UNLIKELY( Hdr.cbIn < sizeof(Hdr) || (Hdr.cbOut < sizeof(Hdr) && Hdr.cbOut != 0) || cbReq > _1M*16)) { LogRel(("vgdrvFreeBSDIOCtlSlow: max(%#x,%#x); ulCmd=%#lx\n", Hdr.cbIn, Hdr.cbOut, ulCmd)); return EINVAL; } /* * Allocate buffer and copy in the data. */ pHdr = (PVBGLREQHDR)RTMemTmpAlloc(cbReq); if (RT_UNLIKELY(!pHdr)) { LogRel(("vgdrvFreeBSDIOCtlSlow: failed to allocate buffer of %d bytes; ulCmd=%#lx\n", cbReq, ulCmd)); return ENOMEM; } rc = copyin(pvUser, pHdr, Hdr.cbIn); if (RT_UNLIKELY(rc)) { LogRel(("vgdrvFreeBSDIOCtlSlow: copyin(%p,%p,%#x) -> %#x; ulCmd=%#lx\n", pvUser, pHdr, Hdr.cbIn, rc, ulCmd)); RTMemTmpFree(pHdr); return rc; } if (Hdr.cbIn < cbReq) RT_BZERO((uint8_t *)pHdr + Hdr.cbIn, cbReq - Hdr.cbIn); } else { Log(("vgdrvFreeBSDIOCtlSlow: huh? cbReq=%#x ulCmd=%#lx\n", cbReq, ulCmd)); return EINVAL; } /* * Process the IOCtl. */ int rc = VGDrvCommonIoCtl(ulCmd, &g_DevExt, pSession, pHdr, cbReq); if (RT_LIKELY(!rc)) { /* * If unbuffered, copy back the result before returning. */ if (pvUser) { uint32_t cbOut = pHdr->cbOut; if (cbOut > cbReq) { LogRel(("vgdrvFreeBSDIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cbReq, ulCmd)); cbOut = cbReq; } rc = copyout(pHdr, pvUser, cbOut); if (RT_UNLIKELY(rc)) LogRel(("vgdrvFreeBSDIOCtlSlow: copyout(%p,%p,%#x) -> %d; uCmd=%#lx!\n", pHdr, pvUser, cbOut, rc, ulCmd)); Log(("vgdrvFreeBSDIOCtlSlow: returns %d / %d ulCmd=%lx\n", 0, pHdr->rc, ulCmd)); /* cleanup */ RTMemTmpFree(pHdr); } } else { /* * The request failed, just clean up. */ if (pvUser) RTMemTmpFree(pHdr); Log(("vgdrvFreeBSDIOCtlSlow: ulCmd=%lx pData=%p failed, rc=%d\n", ulCmd, pvData, rc)); rc = EINVAL; } return rc; }
/** * Tests if the given string is a valid IPv6 address. * * @returns 0 if valid, some random number if not. THIS IS NOT AN IPRT STATUS! * @param psz The string to test * @param pszResultAddress plain address, optional read "valid addresses * and strings" above. * @param resultAddressSize size of pszResultAddress * @param addressOnly return only the plain address (no scope) * Ignored, and will always return the if id */ static int rtNetIpv6CheckAddrStr(const char *psz, char *pszResultAddress, size_t resultAddressSize, bool addressOnly, bool followRfc) { int rc; int rc2; int returnValue; char *p = NULL, *pl = NULL; size_t memAllocMaxSize = RT_MAX(strlen(psz), resultAddressSize) + 40; char *pszAddressOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize); char *pszIfIdOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize); char *pszAddressRfcOutLocal = (char *)RTMemTmpAlloc(memAllocMaxSize); if (!pszAddressOutLocal || !pszIfIdOutLocal || !pszAddressRfcOutLocal) return VERR_NO_TMP_MEMORY; memset(pszAddressOutLocal, '\0', memAllocMaxSize); memset(pszIfIdOutLocal, '\0', memAllocMaxSize); memset(pszAddressRfcOutLocal, '\0', memAllocMaxSize); rc = rtStrParseAddrStr6(psz, strlen(psz), pszAddressOutLocal, memAllocMaxSize, NULL, pszIfIdOutLocal, memAllocMaxSize, NULL, NULL, followRfc); if (rc == 0) returnValue = VINF_SUCCESS; if (rc == 0 && pszResultAddress) { // convert the 32 characters to a valid, shortened ipv6 address rc2 = rtStrToIpAddr6Str((const char *)pszAddressOutLocal, pszAddressRfcOutLocal, memAllocMaxSize, NULL, 0, followRfc); if (rc2 != 0) returnValue = 951; // this is a temporary solution if (!returnValue && strlen(pszIfIdOutLocal) > 0) // the if identifier is copied over _ALWAYS_ && !addressOnly) { p = pszAddressRfcOutLocal + strlen(pszAddressRfcOutLocal); *p = '%'; p++; pl = (char *)memcpy(p, pszIfIdOutLocal, strlen(pszIfIdOutLocal)); if (!pl) returnValue = VERR_NOT_SUPPORTED; } pl = NULL; pl = (char *)memcpy(pszResultAddress, pszAddressRfcOutLocal, strlen(pszAddressRfcOutLocal)); if (!pl) returnValue = VERR_NOT_SUPPORTED; } if (rc != 0) returnValue = VERR_NOT_SUPPORTED; if (pszAddressOutLocal) RTMemTmpFree(pszAddressOutLocal); if (pszAddressRfcOutLocal) RTMemTmpFree(pszAddressRfcOutLocal); if (pszIfIdOutLocal) RTMemTmpFree(pszIfIdOutLocal); return returnValue; }
/** * Worker for VBoxServiceGetFileVersionString. * * @returns VBox status code. * @param pszFilename ASCII & ANSI & UTF-8 compliant name. */ static int VBoxServiceGetFileVersion(const char *pszFilename, PDWORD pdwMajor, PDWORD pdwMinor, PDWORD pdwBuildNumber, PDWORD pdwRevisionNumber) { int rc; *pdwMajor = *pdwMinor = *pdwBuildNumber = *pdwRevisionNumber = 0; /* * Get the file version info. */ DWORD dwHandleIgnored; DWORD cbVerData = GetFileVersionInfoSizeA(pszFilename, &dwHandleIgnored); if (cbVerData) { LPTSTR pVerData = (LPTSTR)RTMemTmpAllocZ(cbVerData); if (pVerData) { if (GetFileVersionInfoA(pszFilename, dwHandleIgnored, cbVerData, pVerData)) { /* * Try query and parse the FileVersion string our selves first * since this will give us the correct revision number when * it goes beyond the range of an uint16_t / WORD. */ if (VBoxServiceGetFileVersionOwn(pVerData, pdwMajor, pdwMinor, pdwBuildNumber, pdwRevisionNumber)) rc = VINF_SUCCESS; else { /* Fall back on VS_FIXEDFILEINFO */ UINT cbFileInfoIgnored = 0; VS_FIXEDFILEINFO *pFileInfo = NULL; if (VerQueryValue(pVerData, "\\", (LPVOID *)&pFileInfo, &cbFileInfoIgnored)) { *pdwMajor = HIWORD(pFileInfo->dwFileVersionMS); *pdwMinor = LOWORD(pFileInfo->dwFileVersionMS); *pdwBuildNumber = HIWORD(pFileInfo->dwFileVersionLS); *pdwRevisionNumber = LOWORD(pFileInfo->dwFileVersionLS); rc = VINF_SUCCESS; } else { rc = RTErrConvertFromWin32(GetLastError()); VBoxServiceVerbose(3, "No file version value for file \"%s\" available! (%d / rc=%Rrc)\n", pszFilename, GetLastError(), rc); } } } else { rc = RTErrConvertFromWin32(GetLastError()); VBoxServiceVerbose(0, "GetFileVersionInfo(%s) -> %u / %Rrc\n", pszFilename, GetLastError(), rc); } RTMemTmpFree(pVerData); } else { VBoxServiceVerbose(0, "Failed to allocate %u byte for file version info for '%s'\n", cbVerData, pszFilename); rc = VERR_NO_TMP_MEMORY; } } else { rc = RTErrConvertFromWin32(GetLastError()); VBoxServiceVerbose(3, "GetFileVersionInfoSize(%s) -> %u / %Rrc\n", pszFilename, GetLastError(), rc); } return rc; }
/** * Relocates the RC address space. * * @param pUVM The user mode VM handle. * @param offDelta The relocation delta. */ void dbgfR3AsRelocate(PUVM pUVM, RTGCUINTPTR offDelta) { /* * We will relocate the raw-mode context modules by offDelta if they have * been injected into the the DBGF_AS_RC map. */ if ( pUVM->dbgf.s.afAsAliasPopuplated[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)] && offDelta != 0) { RTDBGAS hAs = pUVM->dbgf.s.ahAsAliases[DBGF_AS_ALIAS_2_INDEX(DBGF_AS_RC)]; /* Take a snapshot of the modules as we might have overlapping addresses between the previous and new mapping. */ RTDbgAsLockExcl(hAs); uint32_t cModules = RTDbgAsModuleCount(hAs); if (cModules > 0 && cModules < _4K) { struct DBGFASRELOCENTRY { RTDBGMOD hDbgMod; RTRCPTR uOldAddr; } *paEntries = (struct DBGFASRELOCENTRY *)RTMemTmpAllocZ(sizeof(paEntries[0]) * cModules); if (paEntries) { /* Snapshot. */ for (uint32_t i = 0; i < cModules; i++) { paEntries[i].hDbgMod = RTDbgAsModuleByIndex(hAs, i); AssertLogRelMsg(paEntries[i].hDbgMod != NIL_RTDBGMOD, ("iModule=%#x\n", i)); RTDBGASMAPINFO aMappings[1] = { { 0, 0 } }; uint32_t cMappings = 1; int rc = RTDbgAsModuleQueryMapByIndex(hAs, i, &aMappings[0], &cMappings, 0 /*fFlags*/); if (RT_SUCCESS(rc) && cMappings == 1 && aMappings[0].iSeg == NIL_RTDBGSEGIDX) paEntries[i].uOldAddr = (RTRCPTR)aMappings[0].Address; else AssertLogRelMsgFailed(("iModule=%#x rc=%Rrc cMappings=%#x.\n", i, rc, cMappings)); } /* Unlink them. */ for (uint32_t i = 0; i < cModules; i++) { int rc = RTDbgAsModuleUnlink(hAs, paEntries[i].hDbgMod); AssertLogRelMsg(RT_SUCCESS(rc), ("iModule=%#x rc=%Rrc hDbgMod=%p\n", i, rc, paEntries[i].hDbgMod)); } /* Link them at the new locations. */ for (uint32_t i = 0; i < cModules; i++) { RTRCPTR uNewAddr = paEntries[i].uOldAddr + offDelta; int rc = RTDbgAsModuleLink(hAs, paEntries[i].hDbgMod, uNewAddr, RTDBGASLINK_FLAGS_REPLACE); AssertLogRelMsg(RT_SUCCESS(rc), ("iModule=%#x rc=%Rrc hDbgMod=%p %RRv -> %RRv\n", i, rc, paEntries[i].hDbgMod, paEntries[i].uOldAddr, uNewAddr)); RTDbgModRelease(paEntries[i].hDbgMod); } RTMemTmpFree(paEntries); } else AssertLogRelMsgFailed(("No memory for %#x modules.\n", cModules)); } else AssertLogRelMsgFailed(("cModules=%#x\n", cModules)); RTDbgAsUnlockExcl(hAs); } }
void vbglR3GRFree(VMMDevRequestHeader *pReq) { RTMemTmpFree(pReq); }
RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t cbBuf) { AssertPtrReturn(pszBuf, VERR_INVALID_POINTER); AssertReturn(cbBuf > 0, VERR_INVALID_PARAMETER); *pszBuf = '\0'; AssertReturn(enmString > RTSYSDMISTR_INVALID && enmString < RTSYSDMISTR_END, VERR_INVALID_PARAMETER); CFStringRef PropStringRef = NULL; switch (enmString) { case RTSYSDMISTR_PRODUCT_NAME: PropStringRef = CFSTR(PROP_PRODUCT_NAME); break; case RTSYSDMISTR_PRODUCT_VERSION: PropStringRef = CFSTR(PROP_PRODUCT_VERSION); break; case RTSYSDMISTR_PRODUCT_SERIAL: PropStringRef = CFSTR(PROP_PRODUCT_SERIAL); break; case RTSYSDMISTR_PRODUCT_UUID: PropStringRef = CFSTR(PROP_PRODUCT_UUID); break; case RTSYSDMISTR_MANUFACTURER: PropStringRef = CFSTR(PROP_MANUFACTURER); break; default: return VERR_NOT_SUPPORTED; } mach_port_t MasterPort; kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort); if (kr != kIOReturnSuccess) { if (kr == KERN_NO_ACCESS) return VERR_ACCESS_DENIED; return RTErrConvertFromDarwinIO(kr); } CFDictionaryRef ClassToMatch = IOServiceMatching(IOCLASS_PLATFORMEXPERTDEVICE); if (!ClassToMatch) return VERR_NOT_SUPPORTED; /* IOServiceGetMatchingServices will always consume ClassToMatch. */ io_iterator_t Iterator; kr = IOServiceGetMatchingServices(MasterPort, ClassToMatch, &Iterator); if (kr != kIOReturnSuccess) return RTErrConvertFromDarwinIO(kr); int rc = VERR_NOT_SUPPORTED; io_service_t ServiceObject; while ((ServiceObject = IOIteratorNext(Iterator))) { if ( enmString == RTSYSDMISTR_PRODUCT_NAME || enmString == RTSYSDMISTR_PRODUCT_VERSION || enmString == RTSYSDMISTR_MANUFACTURER ) { CFDataRef DataRef = (CFDataRef)IORegistryEntryCreateCFProperty(ServiceObject, PropStringRef, kCFAllocatorDefault, kNilOptions); if (DataRef) { size_t cbData = CFDataGetLength(DataRef); const char *pchData = (const char *)CFDataGetBytePtr(DataRef); rc = RTStrCopyEx(pszBuf, cbBuf, pchData, cbData); CFRelease(DataRef); break; } } else { CFStringRef StringRef = (CFStringRef)IORegistryEntryCreateCFProperty(ServiceObject, PropStringRef, kCFAllocatorDefault, kNilOptions); if (StringRef) { Boolean fRc = CFStringGetCString(StringRef, pszBuf, cbBuf, kCFStringEncodingUTF8); if (fRc) rc = VINF_SUCCESS; else { CFIndex cwc = CFStringGetLength(StringRef); size_t cbTmp = cwc + 1; char *pszTmp = (char *)RTMemTmpAlloc(cbTmp); int cTries = 1; while ( pszTmp && (fRc = CFStringGetCString(StringRef, pszTmp, cbTmp, kCFStringEncodingUTF8)) == FALSE && cTries++ < 4) { RTMemTmpFree(pszTmp); cbTmp *= 2; pszTmp = (char *)RTMemTmpAlloc(cbTmp); } if (fRc) rc = RTStrCopy(pszBuf, cbBuf, pszTmp); else if (!pszTmp) rc = VERR_NO_TMP_MEMORY; else rc = VERR_ACCESS_DENIED; RTMemFree(pszTmp); } CFRelease(StringRef); break; } } } IOObjectRelease(ServiceObject); IOObjectRelease(Iterator); return rc; }
/** * Cleans up a GMMR0AllocatePages request. * @param pReq Pointer to the request (returned by GMMR3AllocatePagesPrepare). */ GMMR3DECL(void) GMMR3AllocatePagesCleanup(PGMMALLOCATEPAGESREQ pReq) { RTMemTmpFree(pReq); }