/** * @callback_method_impl{FNRTSTRSPACECALLBACK, Finds the first missing.} */ static DECLCALLBACK(int) rtManifestEntryFindMissing2(PRTSTRSPACECORE pStr, void *pvUser) { PRTMANIFESTEQUALS pEquals = (PRTMANIFESTEQUALS)pvUser; PRTMANIFESTENTRY pEntry = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore); /* * Already visited? */ if (pEntry->fVisited) return 0; /* * Ignore this entry? */ char const * const *ppsz = pEquals->papszIgnoreEntries; if (ppsz) { while (*ppsz) { if (!strcmp(*ppsz, pEntry->StrCore.pszString)) return 0; ppsz++; } } /* * Gotcha! */ RTStrPrintf(pEquals->pszError, pEquals->cbError, "'%s' was not found in the 1st manifest", pEntry->StrCore.pszString); return VERR_NOT_EQUAL; }
/** * @callback_method_impl{FNRTSTRSPACECALLBACK, Destroys RTMANIFESTENTRY.} */ static DECLCALLBACK(int) rtManifestDestroyEntry(PRTSTRSPACECORE pStr, void *pvUser) { PRTMANIFESTENTRY pEntry = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore); RTStrSpaceDestroy(&pEntry->Attributes, rtManifestDestroyAttribute, pvUser); RTMemFree(pEntry); return 0; }
/** * @callback_method_impl{FNRTSTRSPACECALLBACK, Prepare equals operation.} */ static DECLCALLBACK(int) rtManifestAttributeClearVisited(PRTSTRSPACECORE pStr, void *pvUser) { PRTMANIFESTATTR pAttr = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore); pAttr->fVisited = false; NOREF(pvUser); return 0; }
/** * Query an address space by process ID. * * @returns Retained address space handle if found, NIL_RTDBGAS if not. * * @param pVM Pointer to the VM. * @param ProcId The process ID. */ VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PVM pVM, RTPROCESS ProcId) { /* * Validate the input. */ VM_ASSERT_VALID_EXT_RETURN(pVM, NIL_RTDBGAS); AssertReturn(ProcId != NIL_RTPROCESS, NIL_RTDBGAS); /* * Look it up in the PID tree and retain the result. */ RTDBGAS hDbgAs = NIL_RTDBGAS; DBGF_AS_DB_LOCK_READ(pVM); PAVLU32NODECORE pNode = RTAvlU32Get(&pVM->dbgf.s.AsPidTree, ProcId); if (pNode) { PDBGFASDBNODE pDbNode = RT_FROM_MEMBER(pNode, DBGFASDBNODE, PidCore); hDbgAs = (RTDBGAS)pDbNode->HandleCore.Key; uint32_t cRefs = RTDbgAsRetain(hDbgAs); if (RT_UNLIKELY(cRefs == UINT32_MAX)) hDbgAs = NIL_RTDBGAS; } DBGF_AS_DB_UNLOCK_READ(pVM); return hDbgAs; }
/** * Query an address space by name. * * @returns Retained address space handle if found, NIL_RTDBGAS if not. * * @param pVM Pointer to the VM. * @param pszName The name. */ VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PVM pVM, const char *pszName) { /* * Validate the input. */ VM_ASSERT_VALID_EXT_RETURN(pVM, NIL_RTDBGAS); AssertPtrReturn(pszName, NIL_RTDBGAS); AssertReturn(*pszName, NIL_RTDBGAS); /* * Look it up in the string space and retain the result. */ RTDBGAS hDbgAs = NIL_RTDBGAS; DBGF_AS_DB_LOCK_READ(pVM); PRTSTRSPACECORE pNode = RTStrSpaceGet(&pVM->dbgf.s.AsNameSpace, pszName); if (pNode) { PDBGFASDBNODE pDbNode = RT_FROM_MEMBER(pNode, DBGFASDBNODE, NameCore); hDbgAs = (RTDBGAS)pDbNode->HandleCore.Key; uint32_t cRefs = RTDbgAsRetain(hDbgAs); if (RT_UNLIKELY(cRefs == UINT32_MAX)) hDbgAs = NIL_RTDBGAS; } DBGF_AS_DB_UNLOCK_READ(pVM); return hDbgAs; }
/** * OS specific free function. */ DECLHIDDEN(void) rtR0MemFree(PRTMEMHDR pHdr) { pHdr->u32Magic += 1; if (pHdr->fFlags & RTMEMHDR_FLAG_KMALLOC) kfree(pHdr); #ifdef RTMEMALLOC_EXEC_HEAP else if (pHdr->fFlags & RTMEMHDR_FLAG_EXEC_HEAP) { RTSpinlockAcquire(g_HeapExecSpinlock); RTHeapSimpleFree(g_HeapExec, pHdr); RTSpinlockRelease(g_HeapExecSpinlock); } #endif #ifdef RTMEMALLOC_EXEC_VM_AREA else if (pHdr->fFlags & RTMEMHDR_FLAG_EXEC_VM_AREA) { PRTMEMLNXHDREX pHdrEx = RT_FROM_MEMBER(pHdr, RTMEMLNXHDREX, Hdr); size_t iPage = pHdrEx->pVmArea->nr_pages; struct page **papPages = pHdrEx->pVmArea->pages; void *pvMapping = pHdrEx->pVmArea->addr; vunmap(pvMapping); while (iPage-- > 0) __free_page(papPages[iPage]); kfree(papPages); } #endif else vfree(pHdr); }
/** * @interface_method_impl(PDMINVRAM,pfnStoreNvramValue) */ DECLCALLBACK(int) drvNvram_pfnStoreNvramValue(PPDMINVRAM pInterface, int idxVariable, RTUUID *pVendorUuid, const char *pcszVariableName, size_t cbVariableName, uint8_t *pu8Value, size_t cbValue) { int rc = VINF_SUCCESS; char szExtraDataKey[256]; char szExtraDataValue[1024]; LogFlowFunc(("ENTER: pVendorUuid:%RTuuid, pcszVariableName:%s, cbVariableName:%d, pu8Value:%.*Rhxs, cbValue:%d\n", pVendorUuid, pcszVariableName, cbVariableName, cbValue, pu8Value, cbValue)); PNVRAM pThis = RT_FROM_MEMBER(pInterface, NVRAM, INvram); if (!pThis->fPermanentSave) { LogFlowFuncLeaveRC(rc); return rc; } bool fFlushVariable = (!pu8Value); RT_ZERO(szExtraDataKey); RT_ZERO(szExtraDataValue); RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableName", idxVariable); if (!fFlushVariable) RTStrPrintf(szExtraDataValue, 1024, "%s", pcszVariableName); pThis->pNvram->getParent()->machine()->SetExtraData(Bstr(szExtraDataKey).raw(), Bstr(szExtraDataValue).raw()); RT_ZERO(szExtraDataKey); RT_ZERO(szExtraDataValue); RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VendorGuid", idxVariable); if (!fFlushVariable) RTUuidToStr(pVendorUuid, szExtraDataValue, 1024); pThis->pNvram->getParent()->machine()->SetExtraData(Bstr(szExtraDataKey).raw(), Bstr(szExtraDataValue).raw()); RT_ZERO(szExtraDataKey); RT_ZERO(szExtraDataValue); RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableValueLength", idxVariable); if (!fFlushVariable) RTStrPrintf(szExtraDataValue, 1024, "%d", cbValue); pThis->pNvram->getParent()->machine()->SetExtraData(Bstr(szExtraDataKey).raw(), Bstr(szExtraDataValue).raw()); RT_ZERO(szExtraDataKey); RT_ZERO(szExtraDataValue); RTStrPrintf(szExtraDataKey, 256, "VBoxInternal/Devices/efi/0/LUN#0/Config/NVRAM/%d/VariableValue", idxVariable); size_t cbActualSize; if (pu8Value) rc = RTBase64Encode(pu8Value, cbValue, szExtraDataValue, 1024, &cbActualSize); AssertRCReturn(rc, rc); pThis->pNvram->getParent()->machine()->SetExtraData(Bstr(szExtraDataKey).raw(), Bstr(szExtraDataValue).raw()); LogFlowFuncLeaveRC(rc); return rc; }
/** * @interface_method_impl{PDMIBASE,pfnReadControl} */ static DECLCALLBACK(int) drvHostParallelReadControl(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pfReg) { PDRVHOSTPARALLEL pThis = RT_FROM_MEMBER(pInterface, DRVHOSTPARALLEL, CTX_SUFF(IHostParallelConnector)); int rc = VINF_SUCCESS; int rcLnx = 0; uint8_t fReg = 0; # ifndef VBOX_WITH_WIN_PARPORT_SUP rcLnx = ioctl(RTFileToNative(pThis->hFileDevice), PPRCONTROL, &fReg); if (RT_UNLIKELY(rcLnx < 0)) rc = RTErrConvertFromErrno(errno); else { LogFlowFunc(("fReg=%#x\n", fReg)); *pfReg = fReg; } # else /* VBOX_WITH_WIN_PARPORT_SUP */ *pfReg = 0; /* Initialize the buffer*/ if (pThis->fParportAvail) { LogFlowFunc(("calling R0 to read control from parallel port\n")); rc = PDMDrvHlpCallR0(pThis-> CTX_SUFF(pDrvIns), DRVHOSTPARALLELR0OP_READCONTROL, 0); AssertRC(rc); *pfReg = pThis->u8ReadInControl; } # endif /* VBOX_WITH_WIN_PARPORT_SUP */ return rc; }
/** * @interface_method_impl{PDMIBASE, pfnQueryInterface} */ static DECLCALLBACK(void *) gimdevR3QueryInterface(PPDMIBASE pInterface, const char *pszIID) { PGIMDEV pThis = RT_FROM_MEMBER(pInterface, GIMDEV, IDbgBase); PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IDbgBase); PDMIBASE_RETURN_INTERFACE(pszIID, PDMISTREAM, &pThis->IDbgStreamPort); return NULL; }
/** * @interface_method_impl{PDMINETWORKDOWN,pfnReceiveGso} */ static DECLCALLBACK(int) drvR3NetShaperDown_ReceiveGso(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb, PCPDMNETWORKGSO pGso) { PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, INetworkDown); if (pThis->pIAboveNet->pfnReceiveGso) return pThis->pIAboveNet->pfnReceiveGso(pThis->pIAboveNet, pvBuf, cb, pGso); return VERR_NOT_SUPPORTED; }
/** * @interface_method_impl{PDMINETWORKUP,pfnAllocBuf} */ PDMBOTHCBDECL(int) drvNetShaperUp_AllocBuf(PPDMINETWORKUP pInterface, size_t cbMin, PCPDMNETWORKGSO pGso, PPPDMSCATTERGATHER ppSgBuf) { PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp)); if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet))) return VERR_NET_DOWN; //LogFlow(("drvNetShaperUp_AllocBuf: cb=%d\n", cbMin)); STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesRequested, cbMin); STAM_REL_COUNTER_INC(&pThis->StatXmitPktsRequested); #ifdef IN_RING3 if (!PDMR3NsAllocateBandwidth(&pThis->Filter, cbMin)) { STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesDenied, cbMin); STAM_REL_COUNTER_INC(&pThis->StatXmitPktsDenied); return VERR_TRY_AGAIN; } #endif #ifdef IN_RING0 if (!PDMR0NsAllocateBandwidth(&pThis->Filter, cbMin)) { STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesDenied, cbMin); STAM_REL_COUNTER_INC(&pThis->StatXmitPktsDenied); return VERR_TRY_AGAIN; } #endif STAM_REL_COUNTER_ADD(&pThis->StatXmitBytesGranted, cbMin); STAM_REL_COUNTER_INC(&pThis->StatXmitPktsGranted); //LogFlow(("drvNetShaperUp_AllocBuf: got cb=%d\n", cbMin)); return pThis->CTX_SUFF(pIBelowNet)->pfnAllocBuf(pThis->CTX_SUFF(pIBelowNet), cbMin, pGso, ppSgBuf); }
/** * @interface_method_impl{PDMIBASE,pfnQueryInterface} */ static DECLCALLBACK(void *) ps2mQueryInterface(PPDMIBASE pInterface, const char *pszIID) { PPS2M pThis = RT_FROM_MEMBER(pInterface, PS2M, Mouse.IBase); PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->Mouse.IBase); PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUSEPORT, &pThis->Mouse.IPort); return NULL; }
/** * @interface_method_impl{PDMINETWORKUP,pfnNotifyLinkChanged} */ static DECLCALLBACK(void) drvR3NetShaperUp_NotifyLinkChanged(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState) { LogFlow(("drvNetShaperUp_NotifyLinkChanged: enmLinkState=%d\n", enmLinkState)); PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp)); if (pThis->pIBelowNetR3) pThis->pIBelowNetR3->pfnNotifyLinkChanged(pThis->pIBelowNetR3, enmLinkState); }
/** * @interface_method_impl{PDMINETWORKUP,pfnSetPromiscuousMode} */ PDMBOTHCBDECL(void) drvNetShaperUp_SetPromiscuousMode(PPDMINETWORKUP pInterface, bool fPromiscuous) { LogFlow(("drvNetShaperUp_SetPromiscuousMode: fPromiscuous=%d\n", fPromiscuous)); PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp)); if (pThis->CTX_SUFF(pIBelowNet)) pThis->CTX_SUFF(pIBelowNet)->pfnSetPromiscuousMode(pThis->CTX_SUFF(pIBelowNet), fPromiscuous); }
/** * @interface_method_impl{PDMINETWORKUP,pfnFreeBuf} */ PDMBOTHCBDECL(int) drvNetShaperUp_FreeBuf(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf) { PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp)); if (RT_UNLIKELY(!pThis->CTX_SUFF(pIBelowNet))) return VERR_NET_DOWN; return pThis->CTX_SUFF(pIBelowNet)->pfnFreeBuf(pThis->CTX_SUFF(pIBelowNet), pSgBuf); }
/** * @interface_method_impl{PDMINETWORKUP,pfnBeginXmit} */ PDMBOTHCBDECL(int) drvDedicatedNicUp_BeginXmit(PPDMINETWORKUP pInterface, bool fOnWorkerThread) { PDRVDEDICATEDNIC pThis = RT_FROM_MEMBER(pInterface, DRVDEDICATEDNIC, CTX_SUFF(INetworkUp)); int rc = PDMCritSectTryEnter(&pThis->XmitLock); if (RT_SUCCESS(rc)) ASMAtomicUoWriteBool(&pThis->fXmitOnXmitThread, fOnWorkerThread); return rc; }
/** * @interface_method_impl{DBGFINFOHLP,pfnPrintf} */ static DECLCALLBACK(void) dbgcHlpGetDbgfOutputHlp_Printf(PCDBGFINFOHLP pHlp, const char *pszFormat, ...) { PDBGC pDbgc = RT_FROM_MEMBER(pHlp, DBGC, DbgfOutputHlp); va_list va; va_start(va, pszFormat); pDbgc->CmdHlp.pfnPrintfV(&pDbgc->CmdHlp, NULL, pszFormat, va); va_end(va); }
/** * @interface_method_impl{PDMIKEYBOARDCONNECTOR,pfnSetActive} */ DECLCALLBACK(void) Keyboard::i_keyboardSetActive(PPDMIKEYBOARDCONNECTOR pInterface, bool fActive) { PDRVMAINKEYBOARD pDrv = RT_FROM_MEMBER(pInterface, DRVMAINKEYBOARD, IConnector); if (fActive) pDrv->u32DevCaps |= KEYBOARD_DEVCAP_ENABLED; else pDrv->u32DevCaps &= ~KEYBOARD_DEVCAP_ENABLED; }
/** * @callback_method_impl{FNRTSTRSPACECALLBACK, Prepare equals operation.} */ static DECLCALLBACK(int) rtManifestEntryClearVisited(PRTSTRSPACECORE pStr, void *pvUser) { PRTMANIFESTENTRY pEntry = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore); RTStrSpaceEnumerate(&pEntry->Attributes, rtManifestAttributeClearVisited, NULL); pEntry->fVisited = false; NOREF(pvUser); return 0; }
DECLCALLBACK(int) vmmdevSetCredentialsJudgementResult(PPDMIVMMDEVCONNECTOR pInterface, uint32_t u32Flags) { PDRVMAINVMMDEV pDrv = RT_FROM_MEMBER(pInterface, DRVMAINVMMDEV, Connector); if (pDrv->pVMMDev) return pDrv->pVMMDev->SetCredentialsJudgementResult (u32Flags); return VERR_GENERAL_FAILURE; }
/** Destroy a symbol node. */ static DECLCALLBACK(int) rtDbgModContainer_DestroyTreeNode(PAVLRUINTPTRNODECORE pNode, void *pvUser) { PRTDBGMODCTNSYMBOL pSym = RT_FROM_MEMBER(pNode, RTDBGMODCTNSYMBOL, AddrCore); RTStrCacheRelease(g_hDbgModStrCache, pSym->NameCore.pszString); pSym->NameCore.pszString = NULL; RTMemFree(pSym); NOREF(pvUser); return 0; }
RTDECL(uint32_t) RTCrCertCtxRetain(PCRTCRCERTCTX pCertCtx) { AssertPtrReturn(pCertCtx, UINT32_MAX); PRTCRCERTCTXINT pThis = RT_FROM_MEMBER(pCertCtx, RTCRCERTCTXINT, Public); AssertReturn(pThis->u32Magic == RTCRCERTCTXINT_MAGIC, UINT32_MAX); uint32_t cRet = ASMAtomicIncU32(&pThis->cRefs); Assert(cRet < 64); return cRet; }
/** * @callback_method_impl{FNRTSTRSPACECALLBACK, Writes RTMANIFESTENTRY.} */ static DECLCALLBACK(int) rtManifestWriteStdEntry(PRTSTRSPACECORE pStr, void *pvUser) { PRTMANIFESTENTRY pEntry = RT_FROM_MEMBER(pStr, RTMANIFESTENTRY, StrCore); RTMANIFESTWRITESTDATTR Args; Args.hVfsIos = (RTVFSIOSTREAM)pvUser; Args.pszEntry = pStr->pszString; return RTStrSpaceEnumerate(&pEntry->Attributes, rtManifestWriteStdAttr, &Args); }
/** * @callback_method_impl{FNRTSTRSPACECALLBACK, Destroys RTMANIFESTATTR.} */ static DECLCALLBACK(int) rtManifestDestroyAttribute(PRTSTRSPACECORE pStr, void *pvUser) { PRTMANIFESTATTR pAttr = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore); RTStrFree(pAttr->pszValue); pAttr->pszValue = NULL; RTMemFree(pAttr); NOREF(pvUser); return 0; }
/** * Hook function for the thread-resumed event. * * @param pPreemptNotifier Pointer to the preempt_notifier struct. * @param iCpu The CPU this thread is scheduled on. * * @remarks Called without holding the rq (runqueue) lock and with preemption * enabled! */ static void rtThreadCtxHooksLnxSchedIn(struct preempt_notifier *pPreemptNotifier, int iCpu) { PRTTHREADCTXINT pThis = RT_FROM_MEMBER(pPreemptNotifier, RTTHREADCTXINT, hPreemptNotifier); AssertPtr(pThis); AssertPtr(pThis->pfnThreadCtxHook); Assert(pThis->fRegistered); pThis->pfnThreadCtxHook(RTTHREADCTXEVENT_RESUMED, pThis->pvUser); }
/** * @interface_method_impl{PDMINETWORKUP,pfnEndXmit} */ PDMBOTHCBDECL(void) drvNetShaperUp_EndXmit(PPDMINETWORKUP pInterface) { //LogFlow(("drvNetShaperUp_EndXmit:\n")); PDRVNETSHAPER pThis = RT_FROM_MEMBER(pInterface, DRVNETSHAPER, CTX_SUFF(INetworkUp)); if (RT_LIKELY(pThis->CTX_SUFF(pIBelowNet))) pThis->CTX_SUFF(pIBelowNet)->pfnEndXmit(pThis->CTX_SUFF(pIBelowNet)); else PDMCritSectLeave(&pThis->XmitLock); }
DECLCALLBACK(int) vmmdevQueryVisibleRegion(PPDMIVMMDEVCONNECTOR pInterface, uint32_t *pcRect, PRTRECT pRect) { PDRVMAINVMMDEV pDrv = RT_FROM_MEMBER(pInterface, DRVMAINVMMDEV, Connector); Console *pConsole = pDrv->pVMMDev->getParent(); /* Forward to Display, which calls corresponding framebuffers. */ pConsole->i_getDisplay()->i_handleQueryVisibleRegion(pcRect, pRect); return VINF_SUCCESS; }
/** * @callback_method_impl{FNRTSTRSPACECALLBACK, Writes RTMANIFESTATTR.} */ static DECLCALLBACK(int) rtManifestWriteStdAttr(PRTSTRSPACECORE pStr, void *pvUser) { PRTMANIFESTATTR pAttr = RT_FROM_MEMBER(pStr, RTMANIFESTATTR, StrCore); RTMANIFESTWRITESTDATTR *pArgs = (RTMANIFESTWRITESTDATTR *)pvUser; char szLine[RTPATH_MAX + RTSHA512_DIGEST_LEN + 32]; size_t cchLine = RTStrPrintf(szLine, sizeof(szLine), "%s (%s) = %s\n", pAttr->szName, pArgs->pszEntry, pAttr->pszValue); if (cchLine >= sizeof(szLine) - 1) return VERR_BUFFER_OVERFLOW; return RTVfsIoStrmWrite(pArgs->hVfsIos, szLine, cchLine, true /*fBlocking*/, NULL); }
/** * Hook function for the thread-preempting event. * * @param pPreemptNotifier Pointer to the preempt_notifier struct. * @param pNext Pointer to the task that is preempting the * current thread. * * @remarks Called with the rq (runqueue) lock held and with preemption and * interrupts disabled! */ static void rtThreadCtxHooksLnxSchedOut(struct preempt_notifier *pPreemptNotifier, struct task_struct *pNext) { PRTTHREADCTXINT pThis = RT_FROM_MEMBER(pPreemptNotifier, RTTHREADCTXINT, hPreemptNotifier); AssertPtr(pThis); AssertPtr(pThis->pfnThreadCtxHook); Assert(pThis->fRegistered); Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD)); pThis->pfnThreadCtxHook(RTTHREADCTXEVENT_PREEMPTING, pThis->pvUser); }
/** * RTAvlrPVDoWithAll callback. * * @returns 0 to continue the enum, non-zero to quit it. * @param pNode The node. * @param pvUser Pointer to a block pointer variable. For returning * the address of the block to be freed. */ static DECLCALLBACK(int) rtHeapPageFindUnusedBlockCallback(PAVLRPVNODECORE pNode, void *pvUser) { PRTHEAPPAGEBLOCK pBlock = RT_FROM_MEMBER(pNode, RTHEAPPAGEBLOCK, Core); if (pBlock->cFreePages == RTMEMPAGEPOSIX_BLOCK_PAGE_COUNT) { *(PRTHEAPPAGEBLOCK *)pvUser = pBlock; return 1; } return 0; }