示例#1
0
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;
    }
}
示例#2
0
/**
 * 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;
}
示例#4
0
/**
 * 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;
}
示例#5
0
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;
}
示例#6
0
/**
 * 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;
}
示例#7
0
/**
 * 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;
}
示例#8
0
/**
 * 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;
    }
}
示例#11
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;
}
示例#13
0
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;
}
示例#14
0
/**
 * 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;
}
示例#15
0
/**
 * 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;
}
示例#16
0
文件: s3.cpp 项目: mcenirm/vbox
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;
}
示例#19
0
/** @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;
}
示例#21
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   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();
}
示例#24
0
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;
}
示例#26
0
/** @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;
}
示例#27
0
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;
}
示例#28
0
/**
 * 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;
}
示例#29
0
/**
 * 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;
}
示例#30
0
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;
}