static void PNGAPI png_write_data_fn(png_structp png_ptr, png_bytep p, png_size_t cb) { PNGWriteCtx *pCtx = (PNGWriteCtx *)png_get_io_ptr(png_ptr); LogFlowFunc(("png_ptr %p, p %p, cb %d, pCtx %p\n", png_ptr, p, cb, pCtx)); if (pCtx && RT_SUCCESS(pCtx->rc)) { if (pCtx->cbAllocated - pCtx->cbPNG < cb) { uint32_t cbNew = pCtx->cbPNG + (uint32_t)cb; AssertReturnVoidStmt(cbNew > pCtx->cbPNG && cbNew <= _1G, pCtx->rc = VERR_TOO_MUCH_DATA); cbNew = RT_ALIGN_32(cbNew, 4096) + 4096; void *pNew = RTMemRealloc(pCtx->pu8PNG, cbNew); if (!pNew) { pCtx->rc = VERR_NO_MEMORY; return; } pCtx->pu8PNG = (uint8_t *)pNew; pCtx->cbAllocated = cbNew; } memcpy(pCtx->pu8PNG + pCtx->cbPNG, p, cb); pCtx->cbPNG += (uint32_t)cb; } }
/** * Allocates additional space for the block. * * @returns Pointer to the new unused space or NULL if out of memory. * @param pThis The VUSB sniffer instance. * @param cbAdditional The additional memory requested. */ static void *vusbSnifferBlockAllocSpace(PVUSBSNIFFERINT pThis, uint32_t cbAdditional) { /* Fast path where we have enough memory allocated. */ if (pThis->cbBlockCur + cbAdditional <= pThis->cbBlockMax) { void *pv = pThis->pbBlockData + pThis->cbBlockCur; pThis->cbBlockCur += cbAdditional; return pv; } /* Allocate additional memory. */ uint32_t cbNew = pThis->cbBlockCur + cbAdditional; uint8_t *pbDataNew = (uint8_t *)RTMemRealloc(pThis->pbBlockData, cbNew); if (pbDataNew) { pThis->pbBlockData = pbDataNew; pThis->pBlockHdr = (PDumpFileBlockHdr)pbDataNew; void *pv = pThis->pbBlockData + pThis->cbBlockCur; pThis->cbBlockCur = cbNew; pThis->cbBlockMax = cbNew; return pv; } return NULL; }
/** * Appends an already allocated string to papszEnv. * * @returns IPRT status code * @param pIntEnv The environment block to append it to. * @param pszEntry The string to add. Already duplicated, caller * does error cleanup. */ static int rtEnvIntAppend(PRTENVINTERNAL pIntEnv, char *pszEntry) { /* * Do we need to resize the array? */ int rc = VINF_SUCCESS; size_t iVar = pIntEnv->cVars; if (iVar + 2 > pIntEnv->cAllocated) { void *pvNew = RTMemRealloc(pIntEnv->papszEnv, sizeof(char *) * (pIntEnv->cAllocated + RTENV_GROW_SIZE)); if (!pvNew) rc = VERR_NO_MEMORY; else { pIntEnv->papszEnv = (char **)pvNew; pIntEnv->cAllocated += RTENV_GROW_SIZE; for (size_t iNewVar = pIntEnv->cVars; iNewVar < pIntEnv->cAllocated; iNewVar++) pIntEnv->papszEnv[iNewVar] = NULL; } } if (RT_SUCCESS(rc)) { /* * Append it. */ pIntEnv->papszEnv[iVar] = pszEntry; pIntEnv->papszEnv[iVar + 1] = NULL; /* this isn't really necessary, but doesn't hurt. */ pIntEnv->cVars = iVar + 1; } return rc; }
/** * Reallocate the given track list to be able to hold the given number of tracks. * * @returns VBox status code. * @param pTrackList The track list to reallocate. * @param cTracks Number of tracks the list must be able to hold. * @param fFlags Flags for the reallocation. */ static int atapiTrackListReallocate(PTRACKLIST pTrackList, unsigned cTracks, uint32_t fFlags) { int rc = VINF_SUCCESS; if (!(fFlags & ATAPI_TRACK_LIST_REALLOCATE_FLAGS_DONT_CLEAR)) ATAPIPassthroughTrackListClear(pTrackList); if (pTrackList->cTracksMax < cTracks) { PTRACK paTracksNew = (PTRACK)RTMemRealloc(pTrackList->paTracks, cTracks * sizeof(TRACK)); if (paTracksNew) { pTrackList->paTracks = paTracksNew; /* Mark new tracks as undetected. */ for (unsigned i = pTrackList->cTracksMax; i < cTracks; i++) pTrackList->paTracks[i].fFlags |= TRACK_FLAGS_UNDETECTED; pTrackList->cTracksMax = cTracks; } else rc = VERR_NO_MEMORY; } pTrackList->cTracksCurrent = cTracks; return rc; }
static int crSaInsAt(CR_SORTARRAY *pArray, uint32_t iPos, uint64_t element) { if (pArray->cSize == pArray->cBufferSize) { uint32_t cNewBufferSize = pArray->cBufferSize + 16; uint64_t *pNew; if (pArray->pElements) pNew = (uint64_t*)RTMemRealloc(pArray->pElements, cNewBufferSize * sizeof (pArray->pElements[0])); else pNew = (uint64_t*)RTMemAlloc(cNewBufferSize * sizeof (pArray->pElements[0])); if (!pNew) { WARN(("no memory")); return VERR_NO_MEMORY; } pArray->pElements = pNew; pArray->cBufferSize = cNewBufferSize; crSaValidate(pArray); } for (int32_t i = (int32_t)pArray->cSize - 1; i >= (int32_t)iPos; --i) { pArray->pElements[i+1] = pArray->pElements[i]; } pArray->pElements[iPos] = element; ++pArray->cSize; crSaValidate(pArray); return VINF_SUCCESS; }
/** * Appends environment variables to the environment block. * * Each var=value pair is separated by the null character ('\\0'). The whole * block will be stored in one blob and disassembled on the guest side later to * fit into the HGCM param structure. * * @returns VBox status code. * * @param pszEnvVar The environment variable=value to append to the * environment block. * @param ppvList This is actually a pointer to a char pointer * variable which keeps track of the environment block * that we're constructing. * @param pcbList Pointer to the variable holding the current size of * the environment block. (List is a misnomer, go * ahead a be confused.) * @param pcEnvVars Pointer to the variable holding count of variables * stored in the environment block. */ int GuestEnvironment::appendToEnvBlock(const char *pszEnv, void **ppvList, size_t *pcbList, uint32_t *pcEnvVars) { int rc = VINF_SUCCESS; size_t cchEnv = strlen(pszEnv); Assert(cchEnv >= 2); if (*ppvList) { size_t cbNewLen = *pcbList + cchEnv + 1; /* Include zero termination. */ char *pvTmp = (char *)RTMemRealloc(*ppvList, cbNewLen); if (pvTmp == NULL) rc = VERR_NO_MEMORY; else { memcpy(pvTmp + *pcbList, pszEnv, cchEnv); pvTmp[cbNewLen - 1] = '\0'; /* Add zero termination. */ *ppvList = (void **)pvTmp; } } else { char *pszTmp; if (RTStrAPrintf(&pszTmp, "%s", pszEnv) >= 0) { *ppvList = (void **)pszTmp; /* Reset counters. */ *pcEnvVars = 0; *pcbList = 0; } } if (RT_SUCCESS(rc)) { *pcbList += cchEnv + 1; /* Include zero termination. */ *pcEnvVars += 1; /* Increase env variable count. */ } return rc; }
/** * Grows the buffer of a write stream. * * @returns IPRT status code. * @param pStream The stream. Must be in write mode. * @param cbAppending The minimum number of bytes to grow the buffer * with. */ static int scmStreamGrowBuffer(PSCMSTREAM pStream, size_t cbAppending) { size_t cbAllocated = pStream->cbAllocated; cbAllocated += RT_MAX(0x1000 + cbAppending, cbAllocated); cbAllocated = RT_ALIGN(cbAllocated, 0x1000); void *pvNew; if (!pStream->fFileMemory) { pvNew = RTMemRealloc(pStream->pch, cbAllocated); if (!pvNew) return pStream->rc = VERR_NO_MEMORY; } else { pvNew = RTMemDupEx(pStream->pch, pStream->off, cbAllocated - pStream->off); if (!pvNew) return pStream->rc = VERR_NO_MEMORY; RTFileReadAllFree(pStream->pch, pStream->cbAllocated); pStream->fFileMemory = false; } pStream->pch = (char *)pvNew; pStream->cbAllocated = cbAllocated; return VINF_SUCCESS; }
/** * Inserts a node into a directory * * The caller has locked and referenced the directory as well as checked that * the name doesn't already exist within it. On success both the reference and * and link counters will be incremented. * * @returns VBox status code. * * @param pDir The parent directory. Can be NULL when creating the root * directory. * @param pNode The node to insert. */ static int vboxfuseDirInsertChild(PVBOXFUSEDIR pDir, PVBOXFUSENODE pNode) { if (!pDir) { /* * Special case: Root Directory. */ AssertReturn(!g_pTreeRoot, VERR_ALREADY_EXISTS); AssertReturn(pNode->enmType == VBOXFUSETYPE_DIRECTORY, VERR_INTERNAL_ERROR); g_pTreeRoot = (PVBOXFUSEDIR)pNode; } else { /* * Common case. */ if (!(pDir->cEntries % VBOXFUSE_DIR_GROW_BY)) { void *pvNew = RTMemRealloc(pDir->paEntries, sizeof(*pDir->paEntries) * (pDir->cEntries + VBOXFUSE_DIR_GROW_BY)); if (!pvNew) return VERR_NO_MEMORY; pDir->paEntries = (PVBOXFUSENODE *)pvNew; } pDir->paEntries[pDir->cEntries++] = pNode; pDir->Node.cLinks++; } vboxfuseNodeRetain(pNode); pNode->cLinks++; return VINF_SUCCESS; }
static int vbglR3DnDHGProcessSendDataMessages(uint32_t uClientId, uint32_t *puScreenId, char *pszFormat, uint32_t cbFormat, uint32_t *pcbFormatRecv, void **ppvData, uint32_t cbData, size_t *pcbDataRecv) { uint32_t cbDataRecv = 0; int rc = vbglR3DnDHGProcessDataMessageInternal(uClientId, puScreenId, pszFormat, cbFormat, pcbFormatRecv, *ppvData, cbData, &cbDataRecv); size_t cbAllDataRecv = cbDataRecv; while (rc == VERR_BUFFER_OVERFLOW) { uint32_t uNextMsg; uint32_t cNextParms; rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false); if (RT_SUCCESS(rc)) { switch(uNextMsg) { case DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA: { *ppvData = RTMemRealloc(*ppvData, cbAllDataRecv + cbData); if (!*ppvData) { rc = VERR_NO_MEMORY; break; } rc = vbglR3DnDHGProcessMoreDataMessageInternal(uClientId, &((char*)*ppvData)[cbAllDataRecv], cbData, &cbDataRecv); cbAllDataRecv += cbDataRecv; break; } case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL: default: { rc = vbglR3DnDHGProcessCancelMessage(uClientId); if (RT_SUCCESS(rc)) rc = VERR_CANCELLED; break; } } } } if (RT_SUCCESS(rc)) *pcbDataRecv = cbAllDataRecv; return rc; }
void sbreserve(PNATState pData, struct sbuf *sb, int size) { NOREF(pData); if (sb->sb_data) { /* Already alloced, realloc if necessary */ if (sb->sb_datalen != size) { sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)RTMemRealloc(sb->sb_data, size); sb->sb_cc = 0; if (sb->sb_wptr) sb->sb_datalen = size; else sb->sb_datalen = 0; } } else { sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)RTMemAlloc(size); sb->sb_cc = 0; if (sb->sb_wptr) sb->sb_datalen = size; else sb->sb_datalen = 0; } }
/** * Ensures that there is space for at least @a cNewRanges in the table, * reallocating the table if necessary. * * @returns Pointer to the MSR ranges on success, NULL on failure. On failure * @a *ppaMsrRanges is freed and set to NULL. * @param pVM The cross context VM structure. If NULL, * use the process heap, otherwise the VM's hyper heap. * @param ppaMsrRanges The variable pointing to the ranges (input/output). * @param cMsrRanges The current number of ranges. * @param cNewRanges The number of ranges to be added. */ static PCPUMMSRRANGE cpumR3MsrRangesEnsureSpace(PVM pVM, PCPUMMSRRANGE *ppaMsrRanges, uint32_t cMsrRanges, uint32_t cNewRanges) { uint32_t cMsrRangesAllocated; if (!pVM) cMsrRangesAllocated = RT_ALIGN_32(cMsrRanges, 16); else { /* * We're using the hyper heap now, but when the range array was copied over to it from * the host-context heap, we only copy the exact size and not the ensured size. * See @bugref{7270}. */ cMsrRangesAllocated = cMsrRanges; } if (cMsrRangesAllocated < cMsrRanges + cNewRanges) { void *pvNew; uint32_t cNew = RT_ALIGN_32(cMsrRanges + cNewRanges, 16); if (pVM) { Assert(ppaMsrRanges == &pVM->cpum.s.GuestInfo.paMsrRangesR3); Assert(cMsrRanges == pVM->cpum.s.GuestInfo.cMsrRanges); size_t cb = cMsrRangesAllocated * sizeof(**ppaMsrRanges); size_t cbNew = cNew * sizeof(**ppaMsrRanges); int rc = MMR3HyperRealloc(pVM, *ppaMsrRanges, cb, 32, MM_TAG_CPUM_MSRS, cbNew, &pvNew); if (RT_FAILURE(rc)) { *ppaMsrRanges = NULL; pVM->cpum.s.GuestInfo.paMsrRangesR0 = NIL_RTR0PTR; pVM->cpum.s.GuestInfo.paMsrRangesRC = NIL_RTRCPTR; LogRel(("CPUM: cpumR3MsrRangesEnsureSpace: MMR3HyperRealloc failed. rc=%Rrc\n", rc)); return NULL; } *ppaMsrRanges = (PCPUMMSRRANGE)pvNew; } else { pvNew = RTMemRealloc(*ppaMsrRanges, cNew * sizeof(**ppaMsrRanges)); if (!pvNew) { RTMemFree(*ppaMsrRanges); *ppaMsrRanges = NULL; return NULL; } } *ppaMsrRanges = (PCPUMMSRRANGE)pvNew; } if (pVM) { /* Update R0 and RC pointers. */ Assert(ppaMsrRanges == &pVM->cpum.s.GuestInfo.paMsrRangesR3); pVM->cpum.s.GuestInfo.paMsrRangesR0 = MMHyperR3ToR0(pVM, *ppaMsrRanges); pVM->cpum.s.GuestInfo.paMsrRangesRC = MMHyperR3ToRC(pVM, *ppaMsrRanges); } return *ppaMsrRanges; }
int vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype, uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4) { /* Choose a sane upper limit. */ AssertReturn(reg < _32K, VERR_INVALID_PARAMETER); if (type == SVGA3D_SHADERTYPE_VS) { if (pContext->state.cVertexShaderConst <= reg) { pContext->state.paVertexShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paVertexShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1)); AssertReturn(pContext->state.paVertexShaderConst, VERR_NO_MEMORY); for (uint32_t i = pContext->state.cVertexShaderConst; i < reg + 1; i++) pContext->state.paVertexShaderConst[i].fValid = false; pContext->state.cVertexShaderConst = reg + 1; } pContext->state.paVertexShaderConst[reg].fValid = true; pContext->state.paVertexShaderConst[reg].ctype = ctype; pContext->state.paVertexShaderConst[reg].value[0] = val1; pContext->state.paVertexShaderConst[reg].value[1] = val2; pContext->state.paVertexShaderConst[reg].value[2] = val3; pContext->state.paVertexShaderConst[reg].value[3] = val4; } else { Assert(type == SVGA3D_SHADERTYPE_PS); if (pContext->state.cPixelShaderConst <= reg) { pContext->state.paPixelShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paPixelShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1)); AssertReturn(pContext->state.paPixelShaderConst, VERR_NO_MEMORY); for (uint32_t i = pContext->state.cPixelShaderConst; i < reg + 1; i++) pContext->state.paPixelShaderConst[i].fValid = false; pContext->state.cPixelShaderConst = reg + 1; } pContext->state.paPixelShaderConst[reg].fValid = true; pContext->state.paPixelShaderConst[reg].ctype = ctype; pContext->state.paPixelShaderConst[reg].value[0] = val1; pContext->state.paPixelShaderConst[reg].value[1] = val2; pContext->state.paPixelShaderConst[reg].value[2] = val3; pContext->state.paPixelShaderConst[reg].value[3] = val4; } return VINF_SUCCESS; }
int VDMemDiskSetSize(PVDMEMDISK pMemDisk, uint64_t cbSize) { AssertPtrReturn(pMemDisk, VERR_INVALID_POINTER); if (!pMemDisk->fGrowable) return VERR_NOT_SUPPORTED; if (pMemDisk->cbDisk <= cbSize) { /* Increase. */ pMemDisk->cbDisk = cbSize; } else { /* We have to delete all parts beyond the new end. */ PVDMEMDISKSEG pSeg = (PVDMEMDISKSEG)RTAvlrU64Get(pMemDisk->pTreeSegments, cbSize); if (pSeg) { RTAvlrU64Remove(pMemDisk->pTreeSegments, pSeg->Core.Key); if (pSeg->Core.Key < cbSize) { /* Cut off the part which is not in the file anymore. */ pSeg->pvSeg = RTMemRealloc(pSeg->pvSeg, pSeg->Core.KeyLast - cbSize + 1); pSeg->Core.KeyLast = cbSize - pSeg->Core.Key - 1; bool fInserted = RTAvlrU64Insert(pMemDisk->pTreeSegments, &pSeg->Core); AssertMsg(fInserted, ("Bug!\n")); } else { /* Free the whole block. */ RTMemFree(pSeg->pvSeg); RTMemFree(pSeg); } } /* Kill all blocks coming after. */ do { pSeg = (PVDMEMDISKSEG)RTAvlrU64GetBestFit(pMemDisk->pTreeSegments, cbSize, true); if (pSeg) { RTAvlrU64Remove(pMemDisk->pTreeSegments, pSeg->Core.Key); RTMemFree(pSeg->pvSeg); pSeg->pvSeg = NULL; RTMemFree(pSeg); } else break; } while (true); pMemDisk->cbDisk = cbSize; } return VINF_SUCCESS; }
/** * Schedules the setting of a property. * * @returns IPRT status code. * @retval VERR_INVALID_STATE if not a SVN WC file. * @param pState The rewrite state to work on. * @param pszName The name of the property to set. * @param pszValue The value. NULL means deleting it. */ int ScmSvnSetProperty(PSCMRWSTATE pState, const char *pszName, const char *pszValue) { /* * Update any existing entry first. */ size_t i = pState->cSvnPropChanges; while (i-- > 0) if (!strcmp(pState->paSvnPropChanges[i].pszName, pszName)) { if (!pszValue) { RTStrFree(pState->paSvnPropChanges[i].pszValue); pState->paSvnPropChanges[i].pszValue = NULL; } else { char *pszCopy; int rc = RTStrDupEx(&pszCopy, pszValue); if (RT_FAILURE(rc)) return rc; pState->paSvnPropChanges[i].pszValue = pszCopy; } return VINF_SUCCESS; } /* * Insert a new entry. */ i = pState->cSvnPropChanges; if ((i % 32) == 0) { void *pvNew = RTMemRealloc(pState->paSvnPropChanges, (i + 32) * sizeof(SCMSVNPROP)); if (!pvNew) return VERR_NO_MEMORY; pState->paSvnPropChanges = (PSCMSVNPROP)pvNew; } pState->paSvnPropChanges[i].pszName = RTStrDup(pszName); pState->paSvnPropChanges[i].pszValue = pszValue ? RTStrDup(pszValue) : NULL; if ( pState->paSvnPropChanges[i].pszName && (pState->paSvnPropChanges[i].pszValue || !pszValue) ) pState->cSvnPropChanges = i + 1; else { RTStrFree(pState->paSvnPropChanges[i].pszName); pState->paSvnPropChanges[i].pszName = NULL; RTStrFree(pState->paSvnPropChanges[i].pszValue); pState->paSvnPropChanges[i].pszValue = NULL; return VERR_NO_MEMORY; } return VINF_SUCCESS; }
/** * Grows the line array of a stream. * * @returns IPRT status code. * @param pStream The stream. * @param iMinLine Minimum line number. */ static int scmStreamGrowLines(PSCMSTREAM pStream, size_t iMinLine) { size_t cLinesAllocated = pStream->cLinesAllocated; cLinesAllocated += RT_MAX(512 + iMinLine, cLinesAllocated); cLinesAllocated = RT_ALIGN(cLinesAllocated, 512); void *pvNew = RTMemRealloc(pStream->paLines, cLinesAllocated * sizeof(SCMSTREAMLINE)); if (!pvNew) return pStream->rc = VERR_NO_MEMORY; pStream->paLines = (PSCMSTREAMLINE)pvNew; pStream->cLinesAllocated = cLinesAllocated; return VINF_SUCCESS; }
static size_t rtS3WriteMemoryCallback(void *pvBuf, size_t cSize, size_t cBSize, void *pvUser) { PRTS3TMPMEMCHUNK pTmpMem = (PRTS3TMPMEMCHUNK)pvUser; size_t cRSize = cSize * cBSize; pTmpMem->pszMem = (char*)RTMemRealloc(pTmpMem->pszMem, pTmpMem->cSize + cRSize + 1); if (pTmpMem->pszMem) { memcpy(&(pTmpMem->pszMem[pTmpMem->cSize]), pvBuf, cRSize); pTmpMem->cSize += cRSize; pTmpMem->pszMem[pTmpMem->cSize] = 0; } return cRSize; }
static DECLCALLBACK(size_t) rtHttpWriteData(void *pvBuf, size_t cb, size_t n, void *pvUser) { PRTHTTPMEMCHUNK pMem = (PRTHTTPMEMCHUNK)pvUser; size_t cbAll = cb * n; pMem->pu8Mem = (uint8_t*)RTMemRealloc(pMem->pu8Mem, pMem->cb + cbAll + 1); if (pMem->pu8Mem) { memcpy(&pMem->pu8Mem[pMem->cb], pvBuf, cbAll); pMem->cb += cbAll; pMem->pu8Mem[pMem->cb] = '\0'; } return cbAll; }
/* * For comparing to tstMemAutoPtrDisas1. */ extern "C" int tstMemAutoPtrDisas1PureC(void **ppv) { TSTMEMAUTOPTRSTRUCT *pHandle = (TSTMEMAUTOPTRSTRUCT *)RTMemRealloc(NULL, sizeof(*pHandle)); if (pHandle) { pHandle->a = RTRandU32(); if (pHandle->a < UINT32_MAX / 2) { *ppv = pHandle; return VINF_SUCCESS; } RTMemFree(pHandle); } return VERR_TRY_AGAIN; }
/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnRealloc} */ static DECLCALLBACK(int) rtAsn1DefaultAllocator_Realloc(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ALLOCATION pAllocation, void *pvOld, void **ppvNew, size_t cbNew) { Assert(pvOld); Assert(cbNew); size_t cbAlloc = rtAsn1DefaultAllocator_AlignSize(cbNew); void *pv = RTMemRealloc(pvOld, cbAlloc); if (pv) { *ppvNew = pv; pAllocation->cbAllocated = (uint32_t)cbAlloc; return VINF_SUCCESS; } return VERR_NO_MEMORY; }
/** * Waits for a guest property to be changed. * * @return IPRT status code. * @param hPAM PAM handle. * @param uClientID Guest property service client ID. * @param pszKey Key (name) of guest property to wait for. * @param uTimeoutMS Timeout (in ms) to wait for the change. Specify * RT_INDEFINITE_WAIT to wait indefinitly. */ static int pam_vbox_wait_prop(pam_handle_t *hPAM, uint32_t uClientID, const char *pszKey, uint32_t uTimeoutMS) { AssertPtrReturn(hPAM, VERR_INVALID_POINTER); AssertReturn(uClientID, VERR_INVALID_PARAMETER); AssertPtrReturn(pszKey, VERR_INVALID_POINTER); int rc; /* The buffer for storing the data and its initial size. We leave a bit * of space here in case the maximum values are raised. */ void *pvBuf = NULL; uint32_t cbBuf = GUEST_PROP_MAX_NAME_LEN + GUEST_PROP_MAX_VALUE_LEN + GUEST_PROP_MAX_FLAGS_LEN + _1K; for (int i = 0; i < 10; i++) { void *pvTmpBuf = RTMemRealloc(pvBuf, cbBuf); if (pvTmpBuf) { char *pszName = NULL; char *pszValue = NULL; uint64_t u64TimestampOut = 0; char *pszFlags = NULL; pvBuf = pvTmpBuf; rc = VbglR3GuestPropWait(uClientID, pszKey, pvBuf, cbBuf, 0 /* Last timestamp; just wait for next event */, uTimeoutMS, &pszName, &pszValue, &u64TimestampOut, &pszFlags, &cbBuf); } else rc = VERR_NO_MEMORY; if (rc == VERR_BUFFER_OVERFLOW) { /* Buffer too small, try it with a bigger one next time. */ cbBuf += _1K; continue; /* Try next round. */ } /* Everything except VERR_BUFFER_OVERLOW makes us bail out ... */ break; } return rc; }
/** * Ensures that there is space for at least @a cNewRanges in the table, * reallocating the table if necessary. * * @returns Pointer to the MSR ranges on success, NULL on failure. On failure * @a *ppaMsrRanges is freed and set to NULL. * @param ppaMsrRanges The variable pointing to the ranges (input/output). * @param cMsrRanges The current number of ranges. * @param cNewRanges The number of ranges to be added. */ static PCPUMMSRRANGE cpumR3MsrRangesEnsureSpace(PCPUMMSRRANGE *ppaMsrRanges, uint32_t cMsrRanges, uint32_t cNewRanges) { uint32_t cMsrRangesAllocated = RT_ALIGN_32(cMsrRanges, 16); if (cMsrRangesAllocated < cMsrRanges + cNewRanges) { uint32_t cNew = RT_ALIGN_32(cMsrRanges + cNewRanges, 16); void *pvNew = RTMemRealloc(*ppaMsrRanges, cNew * sizeof(**ppaMsrRanges)); if (!pvNew) { RTMemFree(*ppaMsrRanges); *ppaMsrRanges = NULL; return NULL; } *ppaMsrRanges = (PCPUMMSRRANGE)pvNew; } return *ppaMsrRanges; }
VBoxDbgConsole::backWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten) { VBoxDbgConsole *pThis = VBOXDBGCONSOLE_FROM_DBGCBACK(pBack); int rc = VINF_SUCCESS; pThis->lock(); if (cbBuf + pThis->m_cbOutputBuf >= pThis->m_cbOutputBufAlloc) { size_t cbNew = RT_ALIGN_Z(cbBuf + pThis->m_cbOutputBufAlloc + 1, 1024); void *pv = RTMemRealloc(pThis->m_pszOutputBuf, cbNew); if (!pv) { pThis->unlock(); if (pcbWritten) *pcbWritten = 0; return VERR_NO_MEMORY; } pThis->m_pszOutputBuf = (char *)pv; pThis->m_cbOutputBufAlloc = cbNew; } /* * Add the output. */ memcpy(pThis->m_pszOutputBuf + pThis->m_cbOutputBuf, pvBuf, cbBuf); pThis->m_cbOutputBuf += cbBuf; pThis->m_pszOutputBuf[pThis->m_cbOutputBuf] = '\0'; if (pcbWritten) *pcbWritten = cbBuf; if (ASMAtomicUoReadBool(&pThis->m_fTerminate)) rc = VERR_GENERAL_FAILURE; /* * Tell the GUI thread to draw this text. * We cannot do it from here without frequent crashes. */ if (!pThis->m_fUpdatePending) QApplication::postEvent(pThis, new VBoxDbgConsoleEvent(VBoxDbgConsoleEvent::kUpdate)); pThis->unlock(); return rc; }
void VBoxDbgConsole::commandSubmitted(const QString &rCommand) { Assert(isGUIThread()); lock(); RTSemEventSignal(m_EventSem); QByteArray Utf8Array = rCommand.toUtf8(); const char *psz = Utf8Array.constData(); size_t cb = strlen(psz); /* * Make sure we've got space for the input. */ if (cb + m_cbInputBuf >= m_cbInputBufAlloc) { size_t cbNew = RT_ALIGN_Z(cb + m_cbInputBufAlloc + 1, 128); void *pv = RTMemRealloc(m_pszInputBuf, cbNew); if (!pv) { unlock(); return; } m_pszInputBuf = (char *)pv; m_cbInputBufAlloc = cbNew; } /* * Add the input and output it. */ memcpy(m_pszInputBuf + m_cbInputBuf, psz, cb); m_cbInputBuf += cb; m_pszInputBuf[m_cbInputBuf++] = '\n'; m_pOutput->appendText(rCommand + "\n", true /*fClearSelection*/); m_pOutput->ensureCursorVisible(); m_fInputRestoreFocus = m_pInput->hasFocus(); /* dirty focus hack */ m_pInput->setEnabled(false); Log(("VBoxDbgConsole::commandSubmitted: %s (input-enabled=%RTbool)\n", psz, m_pInput->isEnabled())); unlock(); }
static bool i_vbvaPartialRead(uint8_t **ppu8, uint32_t *pcb, uint32_t cbRecord, VBVAMEMORY *pVbvaMemory) { uint8_t *pu8New; LogFlow(("MAIN::DisplayImpl::vbvaPartialRead: p = %p, cb = %d, cbRecord 0x%08X\n", *ppu8, *pcb, cbRecord)); if (*ppu8) { Assert (*pcb); pu8New = (uint8_t *)RTMemRealloc(*ppu8, cbRecord); } else { Assert (!*pcb); pu8New = (uint8_t *)RTMemAlloc(cbRecord); } if (!pu8New) { /* Memory allocation failed, fail the function. */ Log(("MAIN::vbvaPartialRead: failed to (re)alocate memory for partial record!!! cbRecord 0x%08X\n", cbRecord)); if (*ppu8) { RTMemFree(*ppu8); } *ppu8 = NULL; *pcb = 0; return false; } /* Fetch data from the ring buffer. */ i_vbvaFetchBytes(pVbvaMemory, pu8New + *pcb, cbRecord - *pcb); *ppu8 = pu8New; *pcb = cbRecord; return true; }
/** * Reads the next line from the config stream. * * @returns VBox status code. * @param pCfgTokenizer The config tokenizer. */ static int autostartConfigTokenizerReadNextLine(PCFGTOKENIZER pCfgTokenizer) { int rc = VINF_SUCCESS; if (pCfgTokenizer->fEof) return VERR_EOF; do { rc = RTStrmGetLine(pCfgTokenizer->hStrmConfig, pCfgTokenizer->pszLine, pCfgTokenizer->cbLine); if (rc == VERR_BUFFER_OVERFLOW) { char *pszTmp; pCfgTokenizer->cbLine += 128; pszTmp = (char *)RTMemRealloc(pCfgTokenizer->pszLine, pCfgTokenizer->cbLine); if (pszTmp) pCfgTokenizer->pszLine = pszTmp; else rc = VERR_NO_MEMORY; } } while (rc == VERR_BUFFER_OVERFLOW); if ( RT_SUCCESS(rc) || rc == VERR_EOF) { pCfgTokenizer->iLine++; pCfgTokenizer->cchCurr = 1; pCfgTokenizer->pszLineCurr = pCfgTokenizer->pszLine; if (rc == VERR_EOF) pCfgTokenizer->fEof = true; } return rc; }
/** @copydoc RTDBGMODVTDBG::pfnSegmentAdd */ static DECLCALLBACK(int) rtDbgModContainer_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, size_t cchName, uint32_t fFlags, PRTDBGSEGIDX piSeg) { PRTDBGMODCTN pThis = (PRTDBGMODCTN)pMod->pvDbgPriv; /* * Input validation (the bits the caller cannot do). */ /* Overlapping segments are not yet supported. Will use flags to deal with it if it becomes necessary. */ RTUINTPTR uRvaLast = uRva + RT_MAX(cb, 1) - 1; RTUINTPTR uRvaLastMax = uRvaLast; RTDBGSEGIDX iSeg = pThis->cSegs; while (iSeg-- > 0) { RTUINTPTR uCurRva = pThis->paSegs[iSeg].off; RTUINTPTR uCurRvaLast = uCurRva + RT_MAX(pThis->paSegs[iSeg].cb, 1) - 1; if ( uRva <= uCurRvaLast && uRvaLast >= uCurRva && ( /* HACK ALERT! Allow empty segments to share space (bios/watcom, elf). */ (cb != 0 && pThis->paSegs[iSeg].cb != 0) || ( cb == 0 && uRva != uCurRva && uRva != uCurRvaLast) || ( pThis->paSegs[iSeg].cb == 0 && uCurRva != uRva && uCurRva != uRvaLast) ) ) AssertMsgFailedReturn(("uRva=%RTptr uRvaLast=%RTptr (cb=%RTptr) \"%s\";\n" "uRva=%RTptr uRvaLast=%RTptr (cb=%RTptr) \"%s\" iSeg=%#x\n", uRva, uRvaLast, cb, pszName, uCurRva, uCurRvaLast, pThis->paSegs[iSeg].cb, pThis->paSegs[iSeg].pszName, iSeg), VERR_DBG_SEGMENT_INDEX_CONFLICT); if (uRvaLastMax < uCurRvaLast) uRvaLastMax = uCurRvaLast; } /* Strict ordered segment addition at the moment. */ iSeg = pThis->cSegs; AssertMsgReturn(!piSeg || *piSeg == NIL_RTDBGSEGIDX || *piSeg == iSeg, ("iSeg=%#x *piSeg=%#x\n", iSeg, *piSeg), VERR_DBG_INVALID_SEGMENT_INDEX); /* * Add an entry to the segment table, extending it if necessary. */ if (!(iSeg % 8)) { void *pvSegs = RTMemRealloc(pThis->paSegs, sizeof(RTDBGMODCTNSEGMENT) * (iSeg + 8)); if (!pvSegs) return VERR_NO_MEMORY; pThis->paSegs = (PRTDBGMODCTNSEGMENT)pvSegs; } pThis->paSegs[iSeg].SymAddrTree = NULL; pThis->paSegs[iSeg].LineAddrTree = NULL; pThis->paSegs[iSeg].off = uRva; pThis->paSegs[iSeg].cb = cb; pThis->paSegs[iSeg].fFlags = fFlags; pThis->paSegs[iSeg].pszName = RTStrCacheEnterN(g_hDbgModStrCache, pszName, cchName); if (pThis->paSegs[iSeg].pszName) { if (piSeg) *piSeg = iSeg; pThis->cSegs++; pThis->cb = uRvaLastMax + 1; if (!pThis->cb) pThis->cb = RTUINTPTR_MAX; return VINF_SUCCESS; } return VERR_NO_MEMORY; }
int main(int argc, char **argv) { RTR3InitExe(argc, &argv, 0); const char * const argv0 = RTPathFilename(argv[0]); /* options */ uint64_t uAddress = 0; uint64_t uHighlightAddr = UINT64_MAX; ASMSTYLE enmStyle = kAsmStyle_Default; UNDEFOPHANDLING enmUndefOp = kUndefOp_Fail; bool fListing = true; DISCPUMODE enmCpuMode = DISCPUMODE_32BIT; RTFOFF off = 0; RTFOFF cbMax = _1G; bool fHexBytes = false; /* * Parse arguments. */ static const RTGETOPTDEF g_aOptions[] = { { "--address", 'a', RTGETOPT_REQ_UINT64 }, { "--cpumode", 'c', RTGETOPT_REQ_UINT32 }, { "--bytes", 'b', RTGETOPT_REQ_INT64 }, { "--listing", 'l', RTGETOPT_REQ_NOTHING }, { "--no-listing", 'L', RTGETOPT_REQ_NOTHING }, { "--offset", 'o', RTGETOPT_REQ_INT64 }, { "--style", 's', RTGETOPT_REQ_STRING }, { "--undef-op", 'u', RTGETOPT_REQ_STRING }, { "--hex-bytes", 'x', RTGETOPT_REQ_NOTHING }, }; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST); while ( (ch = RTGetOpt(&GetState, &ValueUnion)) && ch != VINF_GETOPT_NOT_OPTION) { switch (ch) { case 'a': uAddress = ValueUnion.u64; break; case 'b': cbMax = ValueUnion.i64; break; case 'c': if (ValueUnion.u32 == 16) enmCpuMode = DISCPUMODE_16BIT; else if (ValueUnion.u32 == 32) enmCpuMode = DISCPUMODE_32BIT; else if (ValueUnion.u32 == 64) enmCpuMode = DISCPUMODE_64BIT; else { RTStrmPrintf(g_pStdErr, "%s: Invalid CPU mode value %RU32\n", argv0, ValueUnion.u32); return 1; } break; case 'h': return Usage(argv0); case 'l': fListing = true; break; case 'L': fListing = false; break; case 'o': off = ValueUnion.i64; break; case 's': if (!strcmp(ValueUnion.psz, "default")) enmStyle = kAsmStyle_Default; else if (!strcmp(ValueUnion.psz, "yasm")) enmStyle = kAsmStyle_yasm; else if (!strcmp(ValueUnion.psz, "masm")) { enmStyle = kAsmStyle_masm; RTStrmPrintf(g_pStdErr, "%s: masm style isn't implemented yet\n", argv0); return 1; } else { RTStrmPrintf(g_pStdErr, "%s: unknown assembly style: %s\n", argv0, ValueUnion.psz); return 1; } break; case 'u': if (!strcmp(ValueUnion.psz, "fail")) enmUndefOp = kUndefOp_Fail; else if (!strcmp(ValueUnion.psz, "all")) enmUndefOp = kUndefOp_All; else if (!strcmp(ValueUnion.psz, "db")) enmUndefOp = kUndefOp_DefineByte; else { RTStrmPrintf(g_pStdErr, "%s: unknown undefined opcode handling method: %s\n", argv0, ValueUnion.psz); return 1; } break; case 'x': fHexBytes = true; break; case 'V': RTPrintf("$Revision: $\n"); return 0; default: return RTGetOptPrintError(ch, &ValueUnion); } } int iArg = GetState.iNext - 1; /** @todo Not pretty, add RTGetOptInit flag for this. */ if (iArg >= argc) return Usage(argv0); int rc = VINF_SUCCESS; if (fHexBytes) { /* * Convert the remaining arguments from a hex byte string into * a buffer that we disassemble. */ size_t cb = 0; uint8_t *pb = NULL; for ( ; iArg < argc; iArg++) { char ch2; const char *psz = argv[iArg]; while (*psz) { /** @todo this stuff belongs in IPRT, same stuff as mac address reading. Could be reused for IPv6 with a different item size.*/ /* skip white space, and for the benefit of linux panics '<' and '>'. */ while (RT_C_IS_SPACE(ch2 = *psz) || ch2 == '<' || ch2 == '>' || ch2 == ',' || ch2 == ';') { if (ch2 == '<') uHighlightAddr = uAddress + cb; psz++; } if (ch2 == '0' && (psz[1] == 'x' || psz[1] == 'X')) { psz += 2; ch2 = *psz; } if (!ch2) break; /* one digit followed by a space or EOS, or two digits. */ int iNum = HexDigitToNum(*psz++); if (iNum == -1) return 1; if (!RT_C_IS_SPACE(ch2 = *psz) && ch2 != '\0' && ch2 != '>' && ch2 != ',' && ch2 != ';') { int iDigit = HexDigitToNum(*psz++); if (iDigit == -1) return 1; iNum = iNum * 16 + iDigit; } /* add the byte */ if (!(cb % 4 /*64*/)) { pb = (uint8_t *)RTMemRealloc(pb, cb + 64); if (!pb) { RTPrintf("%s: error: RTMemRealloc failed\n", argv[0]); return 1; } } pb[cb++] = (uint8_t)iNum; } } /* * Disassemble it. */ rc = MyDisasmBlock(argv0, enmCpuMode, uAddress, uHighlightAddr, pb, cb, enmStyle, fListing, enmUndefOp); } else { /* * Process the files. */ for ( ; iArg < argc; iArg++) { /* * Read the file into memory. */ void *pvFile; size_t cbFile; rc = RTFileReadAllEx(argv[iArg], off, cbMax, RTFILE_RDALL_O_DENY_NONE, &pvFile, &cbFile); if (RT_FAILURE(rc)) { RTStrmPrintf(g_pStdErr, "%s: %s: %Rrc\n", argv0, argv[iArg], rc); break; } /* * Disassemble it. */ rc = MyDisasmBlock(argv0, enmCpuMode, uAddress, uHighlightAddr, (uint8_t *)pvFile, cbFile, enmStyle, fListing, enmUndefOp); if (RT_FAILURE(rc)) break; } } return RT_SUCCESS(rc) ? 0 : 1; }
/** * Adds data to the internal parser buffer. Useful if there * are multiple rounds of adding data needed. * * @return IPRT status code. * @param pbData Pointer to data to add. * @param cbData Size (in bytes) of data to add. */ int GuestProcessStream::AddData(const BYTE *pbData, size_t cbData) { AssertPtrReturn(pbData, VERR_INVALID_POINTER); AssertReturn(cbData, VERR_INVALID_PARAMETER); int rc = VINF_SUCCESS; /* Rewind the buffer if it's empty. */ size_t cbInBuf = m_cbSize - m_cbOffset; bool const fAddToSet = cbInBuf == 0; if (fAddToSet) m_cbSize = m_cbOffset = 0; /* Try and see if we can simply append the data. */ if (cbData + m_cbSize <= m_cbAllocated) { memcpy(&m_pbBuffer[m_cbSize], pbData, cbData); m_cbSize += cbData; } else { /* Move any buffered data to the front. */ cbInBuf = m_cbSize - m_cbOffset; if (cbInBuf == 0) m_cbSize = m_cbOffset = 0; else if (m_cbOffset) /* Do we have something to move? */ { memmove(m_pbBuffer, &m_pbBuffer[m_cbOffset], cbInBuf); m_cbSize = cbInBuf; m_cbOffset = 0; } /* Do we need to grow the buffer? */ if (cbData + m_cbSize > m_cbAllocated) { size_t cbAlloc = m_cbSize + cbData; cbAlloc = RT_ALIGN_Z(cbAlloc, _64K); void *pvNew = RTMemRealloc(m_pbBuffer, cbAlloc); if (pvNew) { m_pbBuffer = (uint8_t *)pvNew; m_cbAllocated = cbAlloc; } else rc = VERR_NO_MEMORY; } /* Finally, copy the data. */ if (RT_SUCCESS(rc)) { if (cbData + m_cbSize <= m_cbAllocated) { memcpy(&m_pbBuffer[m_cbSize], pbData, cbData); m_cbSize += cbData; } else rc = VERR_BUFFER_OVERFLOW; } } return rc; }
/** * Reap URBs in-flight on a device. * * @returns Pointer to a completed URB. * @returns NULL if no URB was completed. * @param pProxyDev The device. * @param cMillies Number of milliseconds to wait. Use 0 to not * wait at all. */ static DECLCALLBACK(PVUSBURB) usbProxyWinUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies) { PPRIV_USBW32 pPriv = USBPROXYDEV_2_DATA(pProxyDev, PPRIV_USBW32); AssertReturn(pPriv, NULL); /* * There are some unnecessary calls, just return immediately or * WaitForMultipleObjects will fail. */ if ( pPriv->cQueuedUrbs <= 0 && pPriv->cPendingUrbs == 0) { if ( cMillies != 0 && pPriv->cPendingUrbs == 0) { /* Wait for the wakeup call. */ DWORD cMilliesWait = cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies; DWORD rc = WaitForMultipleObjects(1, &pPriv->hEventWakeup, FALSE, cMilliesWait); } return NULL; } again: /* Check for pending URBs. */ if (pPriv->cPendingUrbs) { RTCritSectEnter(&pPriv->CritSect); /* Ensure we've got sufficient space in the arrays. */ if (pPriv->cQueuedUrbs + pPriv->cPendingUrbs + 1 > pPriv->cAllocatedUrbs) { unsigned cNewMax = pPriv->cAllocatedUrbs + pPriv->cPendingUrbs + 1; void *pv = RTMemRealloc(pPriv->paHandles, sizeof(pPriv->paHandles[0]) * (cNewMax + 1)); /* One extra for the wakeup event. */ if (!pv) { AssertMsgFailed(("RTMemRealloc failed for paHandles[%d]", cNewMax)); //break; } pPriv->paHandles = (PHANDLE)pv; pv = RTMemRealloc(pPriv->paQueuedUrbs, sizeof(pPriv->paQueuedUrbs[0]) * cNewMax); if (!pv) { AssertMsgFailed(("RTMemRealloc failed for paQueuedUrbs[%d]", cNewMax)); //break; } pPriv->paQueuedUrbs = (PQUEUED_URB *)pv; pPriv->cAllocatedUrbs = cNewMax; } /* Copy the pending URBs over. */ for (unsigned i = 0; i < pPriv->cPendingUrbs; i++) { pPriv->paHandles[pPriv->cQueuedUrbs + i] = pPriv->aPendingUrbs[i]->overlapped.hEvent; pPriv->paQueuedUrbs[pPriv->cQueuedUrbs + i] = pPriv->aPendingUrbs[i]; } pPriv->cQueuedUrbs += pPriv->cPendingUrbs; pPriv->cPendingUrbs = 0; pPriv->paHandles[pPriv->cQueuedUrbs] = pPriv->hEventWakeup; pPriv->paHandles[pPriv->cQueuedUrbs + 1] = INVALID_HANDLE_VALUE; RTCritSectLeave(&pPriv->CritSect); } /* * Wait/poll. * * ASSUMPTIONS: * 1. The usbProxyWinUrbReap can not be run concurrently with each other * so racing the cQueuedUrbs access/modification can not occur. * 2. The usbProxyWinUrbReap can not be run concurrently with * usbProxyWinUrbQueue so they can not race the pPriv->paHandles * access/realloc. */ unsigned cQueuedUrbs = ASMAtomicReadU32((volatile uint32_t *)&pPriv->cQueuedUrbs); DWORD cMilliesWait = cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies; PVUSBURB pUrb = NULL; DWORD rc = WaitForMultipleObjects(cQueuedUrbs + 1, pPriv->paHandles, FALSE, cMilliesWait); /* If the wakeup event fired return immediately. */ if (rc == WAIT_OBJECT_0 + cQueuedUrbs) { if (pPriv->cPendingUrbs) goto again; return NULL; } if (rc >= WAIT_OBJECT_0 && rc < WAIT_OBJECT_0 + cQueuedUrbs) { RTCritSectEnter(&pPriv->CritSect); unsigned iUrb = rc - WAIT_OBJECT_0; PQUEUED_URB pQUrbWin = pPriv->paQueuedUrbs[iUrb]; pUrb = pQUrbWin->urb; /* * Remove it from the arrays. */ cQueuedUrbs = --pPriv->cQueuedUrbs; if (cQueuedUrbs != iUrb) { /* Move the array forward */ for (unsigned i=iUrb;i<cQueuedUrbs;i++) { pPriv->paHandles[i] = pPriv->paHandles[i+1]; pPriv->paQueuedUrbs[i] = pPriv->paQueuedUrbs[i+1]; } } pPriv->paHandles[cQueuedUrbs] = pPriv->hEventWakeup; pPriv->paHandles[cQueuedUrbs + 1] = INVALID_HANDLE_VALUE; pPriv->paQueuedUrbs[cQueuedUrbs] = NULL; RTCritSectLeave(&pPriv->CritSect); Assert(cQueuedUrbs == pPriv->cQueuedUrbs); /* * Update the urb. */ pUrb->enmStatus = usbProxyWinStatusToVUsbStatus(pQUrbWin->urbwin.error); pUrb->cbData = (uint32_t)pQUrbWin->urbwin.len; if (pUrb->enmType == VUSBXFERTYPE_ISOC) { for (unsigned i = 0; i < pUrb->cIsocPkts; ++i) { /* NB: Windows won't change the packet offsets, but the packets may * be only partially filled or completely empty. */ pUrb->aIsocPkts[i].enmStatus = usbProxyWinStatusToVUsbStatus(pQUrbWin->urbwin.aIsoPkts[i].stat); pUrb->aIsocPkts[i].cb = pQUrbWin->urbwin.aIsoPkts[i].cb; } } Log(("usbproxy: pUrb=%p (#%d) ep=%d cbData=%d status=%d cIsocPkts=%d ready\n", pUrb, rc - WAIT_OBJECT_0, pQUrbWin->urb->EndPt, pQUrbWin->urb->cbData, pUrb->enmStatus, pUrb->cIsocPkts)); /* free the urb queuing structure */ if (pQUrbWin->overlapped.hEvent != INVALID_HANDLE_VALUE) { CloseHandle(pQUrbWin->overlapped.hEvent); pQUrbWin->overlapped.hEvent = INVALID_HANDLE_VALUE; } RTMemFree(pQUrbWin); } else if ( rc == WAIT_FAILED || (rc >= WAIT_ABANDONED_0 && rc < WAIT_ABANDONED_0 + cQueuedUrbs)) AssertMsgFailed(("USB: WaitForMultipleObjects %d objects failed with rc=%d and last error %d\n", cQueuedUrbs, rc, GetLastError())); return pUrb; }
RTDECL(int) RTGetOptArgvFromString(char ***ppapszArgv, int *pcArgs, const char *pszCmdLine, const char *pszSeparators) { /* * Some input validation. */ AssertPtr(pszCmdLine); AssertPtr(pcArgs); AssertPtr(ppapszArgv); if (!pszSeparators) pszSeparators = " \t\n\r"; else AssertPtr(pszSeparators); size_t const cchSeparators = strlen(pszSeparators); AssertReturn(cchSeparators > 0, VERR_INVALID_PARAMETER); /* * Parse the command line and chop off it into argv individual argv strings. */ int rc = VINF_SUCCESS; const char *pszSrc = pszCmdLine; char *pszDup = (char *)RTMemAlloc(strlen(pszSrc) + 1); char *pszDst = pszDup; if (!pszDup) return VERR_NO_STR_MEMORY; char **papszArgs = NULL; unsigned iArg = 0; while (*pszSrc) { /* Skip stuff */ rc = rtGetOptSkipDelimiters(&pszSrc, pszSeparators, cchSeparators); if (RT_FAILURE(rc)) break; if (!*pszSrc) break; /* Start a new entry. */ if ((iArg % 32) == 0) { void *pvNew = RTMemRealloc(papszArgs, (iArg + 33) * sizeof(char *)); if (!pvNew) { rc = VERR_NO_MEMORY; break; } papszArgs = (char **)pvNew; } papszArgs[iArg++] = pszDst; /* Parse and copy the string over. */ RTUNICP CpQuote = 0; RTUNICP Cp; for (;;) { rc = RTStrGetCpEx(&pszSrc, &Cp); if (RT_FAILURE(rc) || !Cp) break; if (!CpQuote) { if (Cp == '"' || Cp == '\'') CpQuote = Cp; else if (rtGetOptIsCpInSet(Cp, pszSeparators, cchSeparators)) break; else pszDst = RTStrPutCp(pszDst, Cp); } else if (CpQuote != Cp) pszDst = RTStrPutCp(pszDst, Cp); else CpQuote = 0; } *pszDst++ = '\0'; if (RT_FAILURE(rc) || !Cp) break; } if (RT_FAILURE(rc)) { RTMemFree(pszDup); RTMemFree(papszArgs); return rc; } /* * Terminate the array. * Check for empty string to make sure we've got an array. */ if (iArg == 0) { RTMemFree(pszDup); papszArgs = (char **)RTMemAlloc(1 * sizeof(char *)); if (!papszArgs) return VERR_NO_MEMORY; } papszArgs[iArg] = NULL; *pcArgs = iArg; *ppapszArgv = papszArgs; return VINF_SUCCESS; }